微信小程序總結
一、開發前準備
1.設計圖
關于設計圖的尺寸,最好是讓設計師給到我們前端的是750的設計稿,這樣我們在書寫的時候就可以直接將量到的尺寸加上rpx就可以了,不然需要進行換算,有的時候會出現小數的情況,就不是很準確。
關于設計圖的使用,正常情況是從距離膠囊向下5px的地方開始。
關于設計圖的內容,如果沒有特別特殊的情況,最好設計圖的主要內容也是從距離膠囊5px下開始的,微信小程序的頭部最好是純色,不是漸變或者有圖案的。(原生的是這樣,雖然現在有可以支持全屏展示的,但是一些物理事件不好控制,所以不建議使用全屏展示的)
關于設計圖底部按鈕的問題,如果設計圖中有底部按鈕的情況,要提前和設計說明要考慮全面屏的情況,因為按鈕如果太靠下,在全名屏上使用起來可能會不太友好。
2.層級跳轉深度
對于原生小程序來講,頁面之前的跳轉方式有5種。
wx.switchTab
wx.reLaunch
wx.redirectTo
wx.navigateTo
wx.navigateBack(回退)
但是小程序有自己的層級限制,采用wx.navigeteTo的時候最多能跳轉10層(堆棧)。
所以在開發前要看好整個小程序的項目連續最多的跳轉層數是否超過了10層,如果超過,要考慮是否采用框架或者是在交互方式上進行一些變化。
3.請求及接口定義
在請求方式上最好采用自己封裝的形式,盡量不要直接使用wx.request,如果get請求還好,但是post請求會有比較大的坑,為了避免,所以我們盡量采用類似vue項目那樣集中封裝請求的方式。
在接口上,因為小程序一般都需要有認證或者說是token的,所以要先定義好這個是以什么樣的方式來傳過去,比如我們這個項目中的Authorization。
對于處理特殊情況比如400,404,500等狀態,如果項目中所有接口或者說大多數接口都是一樣的處理的話,最好是統一寫一個攔截來統一處理這些,不然每個接口都要處理這些代碼量會非常大,也不好維護,改一點就要動全部。
對于json數據,如果條件允許的話最好是接口先開發好之后前端再來調請求,但是如果時間緊要同時開發的話,我們可以在前端自己起一個服務,專門放json數據,但是這樣的方式只能實現get請求,對于小程序中比如上傳圖片或文件的post請求,就不太好實現了,要特別再處理一下接口request里面的書寫方式。get請求是沒有關系的。
4.關于圖片的存放位置
正常來說,圖片可以存放到項目中,但是由于微信小程序上線是有大小限制的,整體不能超過3兆,所以如果項目中圖片過多的時候建議采用線上的圖片,這樣可以減少本地包的大小。
二、文件結構
每個文件中都有對應改文件的
index.js
index.json? ? (設置本頁面的一些配置)
index.wxml
index.wxss
三、開發中需要注意的一些寫法及問題
1.關于背景圖片
不能直接在wxss文件里引用本地圖片,運行時會報錯“本地資源圖片無法通過wxss獲取,可以使用網絡圖片或者base64,或者使用<image/>標簽”
2.關于更改,使用或設置data里面的數據
使用data里面的數據的時候,不能直接用this.list,要寫成this.data.list才可以取到
更改或者設置data里面的數據的時候,不能直接this.list = 1,要寫成
this.setData({
? ? list:1
})
或者
this.setData({
? ? ['list']:1
?})
3.全局配置
官方文檔:https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/page.html
需要注意一點的是
backgroundColor是設置窗口的背景色,但是大多數時候在蘋果手機上拉和下拉的時候是需要不同的背景顏色的,所以就要需要官網中的另外兩個配置
backgroundColorTop:頂部窗口的背景色
backgroundColorBottom:底部窗口的背景色
這兩個配置是只對ios系統生效的,因為安卓似乎也不需要。
4.生命周期
app.js里面的生命周期
onLaunch:監聽小程序的初始化,當小程序初始化完成的時候,會觸發一次,而且全局也只會觸發一次。
onShow:監聽小程序顯示,當小程序啟動,或從后臺進入前臺,都會觸發onShow
onHide:監聽小程序隱藏,當小程序從前臺進入后臺,會觸發onHide
onError:錯誤監聽函數,當小程序發生腳本錯誤,或者api調用失敗的時候,會觸發onError并帶上錯誤信息。
這里需要注意的是:
正常來說,在重新進入小程序的時候會重新出發一次app.js里面的onLanuch事件的,但是經過實際測試,安卓系統會在重新進入小程序的時候觸發app.js里面的onLanuch事件以及onShow事件,還會清空儲存在app.js里面的全局參數但是ios系統在重新進入小程序的時候不會觸發app.js里面的onLanuch事件以及onShow事件,也不會清空儲存在app.js里面的數據。
頁面里面的生命周期
onReady:一個頁面只會調用一次,代表頁面已經準備妥當,可以和視圖層進行交互,在onLoad之前觸發。
onLoad:一個頁面只會調用一次。可以接收頁面參數,通過options可以獲取wx.navigateTo和wx.redirectTo中的參數。
onShow:每次打開頁面的時候都會調用一次,不管是進入該頁面還是從下一個頁面返回回到這個頁面,或者是從后臺進入前臺,都會觸發。
onHide:頁面隱藏或者進入后臺運行時會觸發。
onUnload:頁面卸載的時候會觸發。
5.關于原生組件
小程序中的原生組件的層級是最高的,不能依靠調節z-index來調整。
小程序中的原生組件的層級是最高的,不能依靠調節z-index來調整。
原生組件:camera,canvas,input(僅在focus的時候為原生組件),live-player,liver-pusher,map,textarea,video。
如果想要覆蓋住這些原生組件可以使用cover-view這個標簽,但是在cover-view中只能存放cover-view或者是cover-image,不能存放其他標簽,否則在真機上不會顯示出來。
如果想要用cover-view來覆蓋原生組件,并且這兩者都是動態的插入到頁面中去的,那一定要保證cover-view和cover-image插入的時機要比原生組件插入的時間晚,否則原生組件依然會蓋住cover-view。
cover-image是不支持base64格式的圖片的。
對于原生組件radio來說,如果后面的內容超過了兩行,那會造成折行的時候前面的按鈕會變形。所以最好是用label和radio共同封裝成一個組件,再進行使用就會避免此類問題。
6.canvas的問題
小程序中生成的canvas默認是透明的,轉成png圖片就是黑色的底,如果想要白色的底需要單獨設置底色為白色。
前端也是單獨可以生成簡單的二維碼的,但是前端再生成二維碼的時候必須要使用canvas標簽才可以。
需要引入一個生成二維碼的js,在需要的頁面中直接使用就可以了
qrcode = new QRCode('canvas', {
? ?? // usingIn: this,
? ?? text: “”,
? ?? image: '',
? ?? width: 150,
? ?? height: 150,
? ?? colorDark: "#000",
? ?? colorLight: "white",
? ?? correctLevel: QRCode.CorrectLevel.H,
});
7.關于系統兼容和機型兼容的問題
(1)標簽方面
在蘋果手機上,如果便簽里面的內容是動態渲染改變的,高度是固定的,使用view標簽的時候,在體驗版上會造成視圖的內容沒有更新,簡單說就是控制臺里面的數據已經變化了,但是視圖展示出來的結果,如果是兩行數據換成一行數據,就會造成第二行文字仍然存在的情況。這個時候,需要考慮把view標簽換成text便簽,即能解決。
(2)css方面
有些手機機型會不兼容flex布局,所以在使用flex布局的時候要慎重(華為mate30pro)
對于字體的粗細問題,蘋果上是有font-weight:lighter,更細,但是安卓不識別。
ios系統在手機屏幕旋轉的時候會造成像素放大的情況,因為正常是以寬750為基數的,橫屏之后基數就變了,橫豎屏來回切換的時候就會造成樣式錯亂,最好的解決辦法就是設計橫豎屏切換的頁面采用px為單位,px為1/2rpx就可以。
(3)js方面
可以獲取當前設備的系統,進而可以做一些由于系統不同而需要書寫的問題。
wx.getSystemInfo({
success(res){}
})
會獲取當前設備的一些信息。
在小程序中點擊事件是不能直接@click="clickButton()"在括號里面帶參數的,需要在點擊的標簽上使用data-headerImag="1",然后在e里面取值,特別注意的是headerImg 被默認為 headerimg,不識別大寫字母。
在iphone下點擊input和picker切換的時候會出現在picker沒消失的時候就調起鍵盤的情況,這時候我們需要手動在input失焦的時候將鍵盤隱藏wx.hideKeyboard()
(4)圖片預覽方面
官方預覽圖片api:wx.previewImage
在安卓和ios上使用此方法預覽png,jpg等格式的圖片完全沒有問題,但是對于base64格式的圖片來說,安卓是ok的,但是ios不可以,預覽不出來。
所以我們需要先將base64格式的圖片保存到本地,進行處理之后再進行預覽。
需要引入一個轉化的js文件,在使用的頁面進行調用
import { base64src } from '../../utils/base64src.js'
Page({
? data: {
?? shareQrImg: "data:image/jpeg;base64,/9j/4AAQSkZJRgA........GASDFKGKF=" //base64圖片
? },
? onLoad: function (options) {
?? base64src(this.data.shareQrImg, res => {
? ?? console.log(res) // 返回圖片地址,直接賦值到image標簽即可
?? });
? },
})
這樣,直接展示返回的結果就可以了,完美兼容ios和安卓。
參考:http://www.lxweimin.com/p/95fd7ede9f35
8.其他問題
(1)關于在小程序中彈窗的問題:
在頁面中出現彈窗,要控制有彈窗出現的時候彈窗背后的內容不滾動。
第一種:采用catchtouchmove = “true”此種方法可以實現彈窗背景不滾動,但是也會導致彈窗自身內容無法滾動。如果彈窗里面的內容不需要滾動,這種方法是最好的。
第二種:利用css定位來實現{{modalFlag?'fd-disScroll':''}}
.fd-disScroll{
?? position:fixed;
?? top:0px;
?? bottom:0px;
?? left:0px;
?? right:0px;
}
此種方法也可以實現彈窗背景不滾動的功能,但是會造成每次彈窗彈出的時候底部頁面都會回到頂部。
第三種方法:利用scroll-view,在頁面可以滾動的時候將scroll-y設置成true,彈窗出來的時候再設置成false,這種方法既可以做到背景不滾動也可以滿足彈窗內部的內容滾動。
但是,這種方式也有缺點,scroll-view與原生組件不兼容,所以在使用的時候要考慮好。
在scroll-view里面的原生組件在滑動屏幕的時候會抖動,為了防止抖動或者說讓抖動減小一點可以在scroll-view外面再套一層view。
(2)上傳圖片---壓縮
一般在上傳圖片之前都是要先壓縮一下的(不然太浪費流量)
官方提供的api:wx.compressImage
wx.compressImage({
? src: '', // 圖片路徑
? quality: 80 // 壓縮質量
})
壓縮質量,范圍0~100,數值越小,質量越低,壓縮率越高(僅對jpg有效)
改方法在ios上是沒有問題的,但是在安卓手機上,每壓縮上傳一張圖片的時候,本地相冊就會多出一張同樣的圖片。所以不能采用官方給出了這個api。
利用canvas來實現,將圖片繪制到canvas上,然后canvas轉圖片的時候,官網提供了一個方法wx.canvasToTempFilePath(Object,object,Object this),這種方式可以指定生成圖片的質量。
具體可參考:https://www.h5w3.com/16671.html
但是,在使用wx.canvasToTempFilePath這種方法來實現的話會出現截取圖片的位置不對的情況,直接執行的話,生成的圖片總是會比原畫布少一部分。在獲得新圖片輸出的時候加一個延時器就可以了。
wx.chooseImage({
?count: 1,
?sizeType: ['compressed'],
?sourceType: ['album', 'camera'],
?success: function (result) {
?console.log('未壓縮上傳圖片的路徑', result)
?const originPath = result.tempFilePaths[0];
?// 獲得原始圖片大小(利用canvas來壓縮圖片)
?wx.getImageInfo({
?src: result.tempFilePaths[0],
?success(res){
?var targetWidth, targetHeight;
?targetHeight = res.height;
?targetWidth = res.width;
?// 更新canvas大小
?_this.setData({
?cw:targetWidth,
?ch:targetHeight
?});
?console.log(targetWidth,targetHeight)
?// 嘗試壓縮文件,創建canvas
?var ctx = wx.createCanvasContext('firstCanvas');
?ctx.clearRect(0,0,targetWidth,targetHeight);
?ctx.drawImage(result.tempFilePaths[0], 0, 0, targetWidth, targetHeight);
?ctx.draw(false,function(){
?// 獲得新圖片輸出
?setTimeout(()=>{
?wx.canvasToTempFilePath({
?canvasId: 'firstCanvas',
?fileType: 'jpg',
?quality: 0.1,
?success: (res) => {}
??}, this)
?},1000)
??})
?}
??})
?},
?})