開發小程式的一些小經驗
part 1: 樣式問題
圖片問題
圖片在微信小程式中可以說是一個神奇的存在。在web開發中,我們會利用圖片的自適應比如百分比而省去不少麻煩,因為高度會自適應。但是小程式中的圖片都有一個初始大小,而且是固定的,無論你的圖片多大多小,都是統一的320px*240px
。雖然作為元件的圖片支援平鋪,剪下等呈現效果,但是容器大小都是固定的,所以每次使用image
我們要想辦法控制圖片的大小。
css控制(大小固定的圖片)
用CSS控制一部分固定比例的圖片,我們可以使用微信自帶的單位rpx
來固定。
image{
width: 128rpx;
height: 128rpx;
}
複製程式碼
動態計算(用於多種不同尺寸的圖片)
如果遇到了內容頁這種,不知道圖片固定尺寸的情況,就只能根據在後端給的圖片尺寸,然後在JS中換算,通過setData設定圖片大小。
this.setData({
imageWidth: 200,
imageHeight: 200
})
複製程式碼
<image style="width:{{imageWidth}}rpx;height:{{imageHeight}}rpx" src="..."></image>
複製程式碼
動態佈局
如果你的頁面需要根據當前頁面,計算的高度和寬度,那麼頁面一定會閃以下,因為wx.getSystemInfo
是非同步的。
wx.getSystemInfo({
success (res) {
console.log(res.pixelRatio)
console.log(res.windowWidth)
console.log(res.windowHeight)
}
})
複製程式碼
如果像解決這個問題,我們可以這樣,設定一個isLoaded的引數,等頁面載入好了再顯示。
<block wx:if="{{isLoaded}}">
</block>
<block wx:else>
</block>
複製程式碼
當然還有一個方法叫做同部wx.getSystemInfoSync
,這樣就不會像非同步那樣閃了。
try {
const res = wx.getSystemInfoSync()
console.log(res.pixelRatio)
console.log(res.windowWidth)
console.log(res.windowHeight)
} catch (e) {
// Do something when catch error
}
複製程式碼
高度100%問題
如何高度百分百,這裡如果page相當於html如果不是100%,那麼即使內部元素設定高度100%也是無效的,因為百分比是相對父元素而定的。如果這張頁面只用於一屏的,那麼我們可以page設定高度100%,但是如果這張頁面我們只是loading的時候需要100%,那麼這個時候我們可以使用vh這個單位,vh相當於把螢幕的高度分為了100份,因此我們100vh就是滿屏的意思。
.onePageWrapper{
height: 100vh;
}
複製程式碼
part 2: 複用問題
CSS複用問題,wxss複用
有時候,我們不想寫重複的CSS,但是又不想寫在全域性app.wxss中。我們只是有幾張頁面需要共享,這個時候可以建立一個wxss,然後匯入當前頁面的wxss。就像下方這樣匯入就可以了。
@import'../public.wxss';
複製程式碼
模板複用問題,wxml複用
重複兩遍以上的都用模板。同樣為了解決重複問題,我們可以定義模板,然後引入模板呼叫模板,這樣可以極大地減少重複程式碼。
定義模板時,使用<template name="usertop"></template>
。
<template name="usertop">
<image src='{{userInfo.avatarUrl}}'></image>
<text>{{userInfo.nickName}}</text>
<view>{{userInfo.userRank.name}}</view>
<view class='rankLevelText'>LV<text>{{userInfo.level}}</text></view>
<view class='userExper' style='width:{{userInfo.bar}}'></view>
</template>
複製程式碼
使用模板時,使用<template is="usertop"/>
。如果是模板的定義和使用在同一張頁面上則不需要匯入,如果是不同頁面則需要使用匯入<import src="../tpl/usertop.wxml" />
。當然模板是需要傳輸資料的,我們該如何傳遞引數呢?很簡單,直接data="{{userInfo}}"
,加上這個引數,我們可以在模板中呼叫名為 userInfo
的物件了。如果是多個物件?而且想要將函式也傳遞過去保定呢?可以這樣寫data="{{userInfo,bindGetUserInfo}}"
,直接將你想要傳遞的引數通過,
分割,掉用的時候bindgetuserinfo="bindGetUserInfo"
即可。
<import src="../tpl/usertop.wxml" />
<template is="usertop" data="{{userInfo}}"/>
複製程式碼
應用元件複用,wxml+wxss+js複用
如果CSS複用和WXML已經不能滿足複用的問題,自定義元件滿足你。比如有個按鈕,每張頁面都有,而且都需要點選迴應相應的操作,如果每個頁面配置,js就需要複製複製複製。如果是自定義元件,直接呼叫即可。而且自定義元件不僅Page可以呼叫,元件之間也可以互相呼叫,只需再json中配置既可以輕鬆呼叫。
首先是建立元件:
然後在json中配置,告訴其他頁面我是不是元件,以及配置頁面需要用到的元件。
{
"component": true,//如果是元件
"usingComponents": {
"my-component-btn": "/component/my-component-btn"//呼叫的元件
}
}
複製程式碼
配置成功之後,直接在wxml中當作原生元件一般使用:
<my-component-btn></my-component-btn>
複製程式碼
part 3:優雅地生成分享
有時候會通過canvas來建立分享圖片,讓使用者下載分享。
步驟:
wx.downloadFile
,所需的遠端圖片(如果需要)- 敲黑板!
wx.createCanvasContext
建立一個canvas物件,獲取<canvas canvas-id="myCanvas" style="width:750px; height:1098px;"/>
,這裡需要主要注意你所建立的圖片要和canvas一樣大小,不然出來的圖片不完整,如果不在wxml中建立canvas,那麼是獲取不到生成的圖片的。 - 隨意畫畫,和H5的canvas語法差不多
wx.canvasToTempFilePath
最後是生成到臨時檔案,不過這邊有一個坑,需要setTimetout一下,應該是eventloop的原因差不多1秒的延遲就可以了。如果直接獲取是獲取不到圖片的。- 最後使用
wx.previewImage
直接開啟圖片。
drawCanvas: function (url) {
wx.downloadFile({
url: url, //僅為示例,並非真實的資源
success: function (res) {
if (res.statusCode === 200) {
const ctx = wx.createCanvasContext('myCanvas')
//隨意畫畫
ctx.drawImage(res.tempFilePath, 0, 0, 750, 1098)
ctx.setFontSize(56)
ctx.setFillStyle("#fff")
ctx.setTextAlign("center");
ctx.fillText("自定義文字", 375, 100)
ctx.draw();
setTimeout(function () {
wx.canvasToTempFilePath({
canvasId: 'myCanvas',
success: function (res) {
console.log("save");
wx.previewImage({
current: '', // 當前顯示圖片的http連結
urls: [res.tempFilePath]
})
},
fail: (res) => {
//失敗的操作
}
})
},1000)
}
}
})
}
複製程式碼