小程式開發整理
使用
uni-app跨端開發框架,代碼寫法與vue2一致,
一、與web開發的區別
1. 運行方式不同
npm run dev:mp-weixin后,用微信開發者工具打開dist中工程,
2. 標簽與web開發不同
標簽的對應關系
| 小程式中使用 | web中使用 |
|---|---|
| view | div |
| text | span |
| image | img |
| navigator | a |
此外,uni-app 還提供scroll-view、swiper等內置組件, |
3. 運行環境從瀏覽器變成v8引擎
不能使用document,window、localstorage、cookie等瀏覽器自帶物件,但是可以使用 uni 提供的 api 替代,
3.1 獲取dom元素
需要用到SelectorQuery 物件,
const query = uni.createSelectorQuery().in(this);
query.select('#id').boundingClientRect(data =https://www.cnblogs.com/culciful/archive/2022/12/21/> {
console.log("得到布局位置資訊" + JSON.stringify(data));
console.log("節點離頁面頂部的距離為" + data.top);
}).exec();
// select 回傳 NodesRef 物件,即為節點資訊,
注:我們常用的
ref獲取dom,不能用在uni-app內置組件上,只能用在自定義組件上,
3.2 資料快取
本地資料快取
// 異步
uni.setStorage({key: '', data: '', success: ()=>{}, fail: ()=>{}, complete: ()=>{}})
uni.getStorage({key: '', success: ()=>{}, fail: ()=>{}, complete: ()=>{}})
uni.removeStorage({key: '', success: ()=>{}, fail: ()=>{}, complete: ()=>{}})
uni.clearStorage()
// 同步
uni.setStorageSync({key: '', data: ''})
uni.getStorageSync({key: ''})
uni.removeStorageSync({key: ''})
uni.clearStorageSync()
// 獲取當前 storage 相關資訊
uni.getStorageInfo({success: (keys, currentSize, limitSize)=>{}})
const {keys, currentSize, limitSize} = uni.getStorageInfoSync();
4. 工程目錄的區別
projectName/src
├── components
├── pages
├── ...
├── pages.json
└── manifest.json
4.1 新增 pages.json
pages.json 檔案用來對 uni-app 進行全域配置,決定頁面檔案的路徑、組件自動引入規則、分包加載配置、視窗樣式、原生的導航欄、底部的原生tabbar 等,
1)組件自動引入規則
"easycom": {
"^tp-(.*)": "@/tp-view-ui/components/tp-$1/tp-$1.vue"
},
通過uni-app的easycom,只要組件安裝在專案的 components 目錄下,并符合 components/組件名稱/組件名稱.vue 目錄結構,就可以不用參考、注冊,直接在頁面中使用,
- kebab-case (短橫線分隔命名)
- PascalCase (首字母大寫命名)
2)頁面檔案路徑
編譯后,pages的第一個路徑會成為首頁
"pages": [
{
"path": "pages/index/indexA",
"style": {
"navigationBarTitleText": "AAA",
"backgroundColor": "#FFFFFF"
}
},
{
"path": "pages/index/indexB",
"style": {
"navigationBarTitleText": "BBB",
"backgroundColor": "#FFFFFF"
}
}
],
3)小程式的分包加載機制
微信小程式每個分包的大小是2M,總體積一共不能超過20M,
在小程式啟動時,默認會下載主包并啟動主包內頁面,當用戶進入分包內某個頁面時,會把對應分包自動下載下來,下載完成后再進行展示,
"subPackages": [
{
"root": "pages/xxxA",
"pages": [{
"path": "list/list",
"style": {}
}]
},
{
"root": "pages/xxxB",
"pages": [{
"path": "detail/detail",
"style": {}
}]
}
],
4.2 新增 manifest.json
manifest.json 檔案是應用的組態檔,用于指定應用的名稱、圖示、權限等,
"mp-weixin": {
/* 微信小程式特有相關 */
"appid": "wx303f35140da12d22",
"setting": {
"urlCheck": true, // 檢查安全域名和 TLS 版本
"minified": true, // 上傳代碼時自動壓縮
"postcss": true, // 上傳代碼時樣式自動補全
"es6": true // ES6 轉 ES5
},
"usingComponents": true, // 全域自定義組件
"permission": { // 小程式介面權限相關設定
"scope.userLocation": {
"desc": "你的位置資訊將用于小程式位置介面的效果展示"
}
}
},
appid:微信小程式的AppID,登錄 微信公眾平臺 申請,
5. CSS 注意事項
5.1 像素單位
uni-app 默認為 rpx,rpx 即回應式 px,一種根據螢屏寬度自適應的動態單位,
一般UI上手機模型寬度為375px,換算關系為 1px = 2rpx,
5.2 布局
推薦使用 flex 布局,
比如上下子元素高度不固定,中間子元素占據剩余空間:

.flex {
display: flex;
flex-direction: column;
height: 600px; /* 父元素一定要指定高度 */
width: 375px;
}
.flex-box1 {
height: 200px;
background: #b7dff0;
}
.flex-box2 {
background-color: #bfa;
flex: auto;
}
.flex-box3 {
height: 200px;
background: #b7dff0;
}
5.3 小程式組件的視圖層級
組件內元素被shadow-root包裹,修改樣式時需要做/deep/穿透,

二、uni-app 的生命周期
1. 應用生命周期
只能在
App.vue里監聽應用的生命周期
| 函式名 | 說明 |
|---|---|
| onLaunch | 當uni-app 初始化完成時觸發(全域只觸發一次) |
| onShow | 當 uni-app 啟動,或從后臺進入前臺顯示 |
| onHide | 當 uni-app 從前臺進入后臺 |
| onError | 當 uni-app 報錯時觸發 |
| onUniNViewMessage | 對 nvue 頁面發送的資料進行監聽,可參考 nvue 向 vue 通訊 |
| onUnhandledRejection | 對未處理的 Promise 拒絕事件監聽函式(2.8.1+) |
| onPageNotFound | 頁面不存在監聽函式 |
| onThemeChange | 監聽系統主題變化 |
2. 頁面生命周期
| 函式名 | 說明 |
|---|---|
| onLoad | 監聽頁面加載,其引數為上個頁面傳遞的資料,引數型別為 Object(用于頁面傳參) |
| onShow | 監聽頁面顯示,頁面每次出現在螢屏上都觸發,包括從下級頁面點回傳露出當前頁面 |
| onReady | 監聽頁面初次渲染完成,注意如果渲染速度快,會在頁面進入影片完成前觸發 |
| onHide | 監聽頁面隱藏 |
| onUnload | 監聽頁面卸載 |
| onResize | 監聽視窗尺寸變化 |
| ... | .... |
微信小程式的頁面生命周期

使用 onl oad 來頁面傳參
//在起始頁面跳轉到test.vue頁面并傳遞引數
uni.navigateTo({
url: 'test?id=1&name=uniapp'
});
// 在test.vue頁面接受引數
export default {
onLoad(option) { //option為object型別,會序列化上個頁面傳遞的引數
console.log(option.id); //列印出上個頁面傳遞的引數,
console.log(option.name); //列印出上個頁面傳遞的引數,
}
}
- 引數復雜的情況
uni.navigateTo({
url: 'test?data='https://www.cnblogs.com/culciful/archive/2022/12/21/+ JSON.stringify(obj)
});
onLoad: function (option) {
const data = https://www.cnblogs.com/culciful/archive/2022/12/21/JSON.parse(option.data);
}
- 引數中出現空格等特殊字符,比如 url
uni.navigateTo({
url: 'test?data='https://www.cnblogs.com/culciful/archive/2022/12/21/+ encodeURIComponent(JSON.stringify(obj))
});
onLoad: function (option) {
const data = https://www.cnblogs.com/culciful/archive/2022/12/21/JSON.parse(decodeURIComponent(option.data));
}
除了
onLoad,還可以用vuex,uni.$on(eventName,callback),uni.$emit(eventName,OBJECT)進行頁面通訊,
3. 組件生命周期
與 vue 標準組件的生命周期相同
| 函式名 | 說明 | 平臺差異說明 |
|---|---|---|
| beforeCreate | 在實體初始化之前被呼叫, | |
| created | 在實體創建完成后被立即呼叫, | |
| beforeMount | 在掛載開始之前被呼叫, | |
| mounted | 掛載到實體上去之后呼叫, | |
| beforeUpdate | 資料更新時呼叫,發生在虛擬 DOM 打補丁之前, | 僅H5平臺支持 |
| updated | 由于資料更改導致的虛擬 DOM 重新渲染和打補丁,在這之后會呼叫該鉤子, | 僅H5平臺支持 |
| beforeDestroy | 實體銷毀之前呼叫,在這一步,實體仍然完全可用, | |
| destroyed | Vue 實體銷毀后呼叫,呼叫后,Vue 實體指示的所有東西都會解系結,所有的事件監聽器會被移除,所有的子實體也會被銷毀, |
三、特點功能整理
1. 二維碼顯示
使用插件 tki-qrcode,uni-app 二維碼生成器,
安裝
npm i tki-qrcode -S
引入
import tkiQrcode from "tki-qrcode";
export default {
components: {tkiQrcode}
}
使用
<tki-qrcode
ref="qRCodeRef"
:val="qrcodeUrl"
:size="424"
:onval="true"
:loadMake="true"
:showLoading="true"
@result="getQrImgUrl" />
屬性
| 屬性名 | 型別 | 默認值 | 可選值 | 說明 |
|---|---|---|---|---|
| size | Number | 200 | 生成的二維碼大小 | |
| unit | String | upx | px | 大小單位尺寸 |
| val | String | 二維碼 | 要生成的內容 | |
| lv | Number | 3(一般不用設定) | 容錯級別 | |
| onval | Boolean | false | 監聽val值變化自動重新生成二維碼 | |
| loadMake | Boolean | false | 組件初始化完成后自動生成二維碼,val需要有值 | |
| showLoading | Boolean | true | false | 是否顯示loading |
| loadingText | String | 二維碼生成中 | loading文字 | |
| ... | ... | ... | ... | ... |
方法
| 方法名 | 引數 | 默認值 | 說明 |
|---|---|---|---|
| _makeCode() | 生成二維碼 | ||
| _clearCode() | 清空二維碼(清空二維碼會觸發result回呼 回傳值為空) | ||
| _saveCode() | 保存二維碼到圖庫 |
事件
| 事件名 | 回傳值 | 說明 |
|---|---|---|
| result | 生成的圖片base64或圖片臨時地址 | 回傳二維碼路徑 注:_clearCode()后回傳空 |
2. 二維碼卡片下載
使用插件xWxmlToCanvas,根據微信小程式wxml-to-canvas封裝,
安裝
npm i x-wxml-to-canvas -S
引入
實測引入node_modules內插件,條件編譯時會走H5,而不是MP(小程式),只有復制到專案內,才會走小程式,
import xWxmlToCanvas from './components/x-wxml-to-canvas/x-wxml-to-canvas';
export default {
components: {xWxmlToCanvas}
}
使用
<xWxmlToCanvas
ref="xWxmlToCanvas"
:hide="true"
:useCORS="true"
:
:height="518"
:xStyle="myStyle"
:xWxml="myWxml">
</xWxmlToCanvas>
屬性
| 欄位 | 型別 | 默認值 | 描述 |
|---|---|---|---|
| hide | Boolean | false | canvas是否在頁面可見 true 通過fixed將canvas移至螢屏外 |
| width | Number | 300 | canvas寬度,單位px |
| height | Number | 300 | canvas高度,單位px |
| xWxml | String | wxml 模板 | |
| xStyle | Object | {} | 樣式 |
| useCORS | Boolean | true | canvas 圖片跨域 |
wxml 模板
-
支持
view、text、image三種標簽,通過 class 匹配 style 物件中的樣式, -
文字必須用
text標簽包含,否則不顯示,動態文字需要動態賦值寬高,否則會截斷不顯示,
const wxml = (projectName, inviteToChainStore, inviteExpiredTime, imgUrl) => `
<view >
<text >${projectName}</text>
<image src="https://www.cnblogs.com/culciful/archive/2022/12/21/${imgUrl}"></image>
<text >${inviteToChainStore}</text>
<view >
<text >${inviteExpiredTime}</text>
<text >TP-LINK商云</text>
</view>
</view>
`;
imgUrl 通過tki-qrcode組件獲取,
樣式
物件屬性值為對應 wxml 標簽的 class 駝峰形式,需為每個元素指定 width 和 height 屬性,否則會導致布局錯誤,
存在多個 className 時,位置靠后的優先級更高,子元素會繼承父級元素的可繼承屬性,
元素均為 flex 布局,left/top 等 僅在 absolute 定位下生效,
const style = (rowLength) => {
let textWidth = 212;
return {
"verticalCenter": {
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
textAlign: 'center',
},
"inviteCard": {
width: 311, // 單位為 px
height: 518,
position: 'relative',
backgroundColor: '#fff',
borderRadius: 16,
},
"projectName": {
marginTop: 32,
fontSize: 16,
lineHeight: '1.2',
height: rowLength * 22,
width: textWidth,
fontWeight: 600,
},
...
};
};
方法
| 方法名 | 描述 | 回傳值 |
|---|---|---|
| renderToCanvas | 將wxml渲染至頁面 | 無 |
| canvasToTempFilePath | 將canvas轉為圖片地址 (H5端 Canvas 內繪制的影像需要支持跨域訪問才能成功) | promise函式,回傳 圖片地址,h5為base64 |
| getCanvasImage | renderToCanvas 與 canvasToTempFilePath 合并 | promise函式,回傳 圖片地址,h5為base64 |
| saveImageToPhotosAlbum | 圖片保存至本地 | promise函式,回傳 true / flase |
this.$refs.xWxmlToCanvas.renderToCanvas().then(() => {
this.$refs.xWxmlToCanvas.canvasToTempFilePath().then(res => {
this.$refs.xWxmlToCanvas.saveImageToPhotosAlbum(res);
});
});
真機除錯不支持
canvas type2d,可用預覽模式,
3. 退出頁面時攔截顯示彈窗
3.1 開啟小程式頁面回傳詢問對話框
watch: {
isChanged:{
handler: function(val) {
//#ifdef MP-WEIXIN
if (val) {
wx.enableAlertBeforeUnload({ // 只有真機會出現
message: this.$t('pStoreInfo.quitConfirm')
});
} else {
wx.disableAlertBeforeUnload();
}
//#endif
},
immediate: true
}
}
樣式簡單時可以使用,

3.2 微信小程式視圖容器 page-container
“假頁”容器組件,效果類似于 popup 彈出層,頁面記憶體在該容器時,當用戶進行回傳操作,關閉該容器不關閉頁面,
<tp-safe-view has-cutline >
<!--彈窗內容-->
<page-container
:show="show"
position="center"
@beforeleave="beforeleave">
<!--頁面主體內容-->
</page-container>
</tp-safe-view>
beforeleave() {} // 離開前觸發
四、其他事項記錄
-
條目之類的有滾動條時和底部or底部按鈕不一定有距離,但拉到底要有
80rpx -
分頁加載一般請求條數為10、20
-
預覽模式,在真機右上角三個點打開除錯使用 vConsole
-
頁面在
onLoad獲取資料傳遞給組件,而組件在created生命周期使用該資料,有時會出現組件未獲取到值的情況,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/540479.html
標籤:其他
