一、概念
mpvue是 美團(tuán) 修改了 Vue.js 的 runtime 和 compiler 使其可以運(yùn)行在小程序環(huán)境中,從而引入了整套 Vue.js 開發(fā)體驗(yàn)的小程序框架。
二、優(yōu)化細(xì)節(jié)
1、實(shí)例生命周期
不同于vue的是我們會(huì)在小程序 onReady 后,再去觸發(fā) vue mounted 生命周期
除了 Vue 本身的生命周期外(詳細(xì)的 vue 生命周期文檔請(qǐng)看生命周期鉤子),mpvue 還兼容了小程序生命周期,這部分生命周期鉤子的來(lái)源于微信小程序的 Page, 除特殊情況外,不建議使用小程序的生命周期鉤子。
2、模板語(yǔ)法
幾乎全支持 官方文檔:模板語(yǔ)法,但需要注意的是:
(1)組件:由于要預(yù)編譯出 wxml,只能使用單文件組件(.vue 組件)的形式進(jìn)行支持,不支持:動(dòng)態(tài)組件,異步組件,自定義 render,inline-template,X-Templates,<script type=\”text/x-template\”> 字符串模版,Slot(scoped 暫時(shí)還沒(méi)做支持)。
(2)不要在選項(xiàng)屬性或回調(diào)上使用箭頭函數(shù),.eg:
//箭頭函數(shù)是和父級(jí)上下文綁定在一起的,this 不會(huì)是如你做預(yù)期的 Vue 實(shí)例,且 this.a 或 this.myMethod 也會(huì)是未定義的created: () => console.log(this.a)vm.$watch(\’a\’, newValue => this.myMethod())
(3) 頁(yè)面 內(nèi)可以通過(guò) this.$root.$mp.query (需要在 onLoad 生命周期觸發(fā)之后使用)獲取小程序在 page onLoad 時(shí)候傳遞的 options(如:query 參數(shù)等)。組件內(nèi)通過(guò)** this.$root.$mp.appOptions**獲取小程序在 app的 onLaunch/onShow 時(shí)候傳遞的 options
(4)mpvue 可以支持小程序的原生組件,建議開發(fā)過(guò)程中直接使用 微信小程序:表單組件,.eg:
<picker mode=\”date\” :value=\”date\” start=\”2015-09-01\” end=\”2017-09-01\” @change=\”bindDateChange\”><!–需要注意的是原生組件上的事件綁定,需要以 vue 的事件綁定語(yǔ)法來(lái)綁定,如 bindchange=\”eventName\” 事件,需要寫成 @change=\”eventName\”–> <view class=\”picker\”> 當(dāng)前選擇: {{date}} </view></picker>
(5)列表渲染,嵌套列表渲染,必須指定不同的索引。示例:
<!– 在這種嵌套循環(huán)的時(shí)候, index 和 itemIndex 這種索引是必須指定,且別名不能相同,正確的寫法如下 –><template> <ul v-for=\”(card, index) in list\”> <li v-for=\”(item, itemIndex) in card\”> {{item.value}} </li> </ul></template>
(6)事件處理器
- 列表中沒(méi)有的原生事件也可以使用例如 bindregionchange 事件直接在 dom 上將bind改為@ @regionchange,同時(shí)這個(gè)事件也非常特殊,它的 event type 有 begin 和 end 兩個(gè),導(dǎo)致我們無(wú)法在handleProxy 中區(qū)分到底是什么事件,所以你在監(jiān)聽此類事件的時(shí)候同時(shí)監(jiān)聽事件名和事件類型既 <map @regionchange=\”functionName\” @end=\”functionName\” @begin=\”functionName\”><map>
- bind 和 catch 事件(.stop 阻止冒泡)同時(shí)綁定時(shí),只觸發(fā) bind ,catch 不會(huì)被觸發(fā)。
- 小程序里沒(méi)有鍵盤事件(鍵盤修飾符),默認(rèn)(.prevent)事件,removeEventListener(.once)事件,.self 沒(méi)有可以判斷的標(biāo)識(shí)
- .capture ( 1.0.9支持)使用捕獲
// 事件映射表,左側(cè)為 WEB 事件,右側(cè)為 小程序 對(duì)應(yīng)事件{ click: \’tap\’, touchstart: \’touchstart\’, touchmove: \’touchmove\’, touchcancel: \’touchcancel\’, touchend: \’touchend\’, tap: \’tap\’, longtap: \’longtap\’, input: \’input\’, change: \’change\’,//在 input 和 textarea 中 change 事件會(huì)被轉(zhuǎn)為 blur 事件 submit: \’submit\’, blur: \’blur\’, focus: \’focus\’, reset: \’reset\’, confirm: \’confirm\’, columnchange: \’columnchange\’, linechange: \’linechange\’, error: \’error\’, scrolltoupper: \’scrolltoupper\’, scrolltolower: \’scrolltolower\’, scroll: \’scroll\’}
(7)因?yàn)榫幾g到 wxml,小程序不會(huì)生成節(jié)點(diǎn),暫不支持在組件上定義 click 等原生事件、v-show(可用 v-if 代替)和 class、 style 等樣式屬性。
<!–不生效,建議寫在內(nèi)部頂級(jí)元素上–><card class=\”class-name\”> </card><card :style=\”{height:10 \’px\’}\”> </card><card @click=\”clickFun\”> </card><card v-show=\”showIf\”> </card>//可用 v-if 代替
(8)不支持在 template 內(nèi)使用 部分復(fù)雜的 Javascript 渲染表達(dá)式,methods 中的函數(shù),過(guò)濾器,v-html 指令。我們會(huì)把 template 中的 {{}} 雙花括號(hào)的部分,直接編碼到 wxml 文件中,由于微信小程序的能力限制(數(shù)據(jù)綁定),所以無(wú)法支持復(fù)雜的 JavaScript 表達(dá)式。目前可以使用的有 – * % ?: ! == === > < [] .,剩下的還待完善。
<!– 這種就不支持,建議寫 computed –><p>{{ message.split(\’\’).reverse().join(\’\’) }}</p><!– 但寫在 @event 里面的表達(dá)式是都支持的,因?yàn)檫@部分的計(jì)算放在了 vdom 里面 –><ul> <li v-for=\”item in list\”> <div @click=\”clickHandle(item, index, $event)\”>{{ item.value }}</p> </li></ul>
(9)不支持keep-alive、transition
(10)不支持 官方文檔:Class 與 Style 綁定 中的 classObject 和 styleObject 語(yǔ)法??梢杂?computed 方法生成 class 或者 style 字符串,從性能考慮,建議不要過(guò)度使用
<template> <!– 支持 –> <div class=\”container\” :class=\”computedClassStr\”></div> <div class=\”container\” :class=\”{active: isActive}\”></div> <!– 不支持 –> <div class=\”container\” :class=\”computedClassObject\”></div></template><script> export default { data () { return { isActive: true } }, computed: { computedClassStr () { return this.isActive ? \’active\’ : \’\’ }, computedClassObject () { return { active: this.isActive } } } }</script>
3、注意事項(xiàng)
(1)開啟單個(gè)頁(yè)面的“下拉刷新”,你需要在該頁(yè)面文件夾中建一個(gè).json文件,在.json文件中配置
{ \”enablePullDownRefresh\”:true}
(2)如果你先全局注冊(cè)store,你需要先在src/main里添加在注冊(cè)到vue實(shí)例中:
Vue.prototype.$store = store
(3)底部導(dǎo)航的圖片你需要放在static文件夾下,否則不會(huì)正常顯示
(3)精簡(jiǎn) data 數(shù)據(jù)。冗余數(shù)據(jù)不要掛在 data 里,所有在 data/props/computed 中的數(shù)據(jù),每次變更都會(huì)從微信小程序的 JSCore 進(jìn)程,通過(guò) setData 序列化成字符串后發(fā)送到 JSRender 進(jìn)程。所以,如果你的數(shù)據(jù)量巨大的時(shí)候,會(huì)導(dǎo)致頁(yè)面非常卡頓。
(4) 優(yōu)化長(zhǎng)列表性能
- 避免在 v-for 中嵌套子組件,這樣可以優(yōu)化大部分部分 setData 時(shí)的冗余數(shù)據(jù)。
- 通過(guò)實(shí)踐發(fā)現(xiàn) wx:if 和 hidden 的優(yōu)化肉眼不可見,所以或許可以試試直接通過(guò)樣式 display 來(lái)展示和隱藏。
(5)建議使用 v-model.lazy 綁定方式以優(yōu)化性能,v-model 在老基礎(chǔ)庫(kù)下輸入框輸入時(shí)可能存在光標(biāo)重設(shè)的問(wèn)題。
(6)如果你有小程序和H5復(fù)用代碼的需要,業(yè)務(wù)代碼需要保持對(duì) WEB Vue.js 的兼容性,建議不要在代碼中直接調(diào)用小程序API,更好的選擇是通過(guò)橋接適配層屏蔽兩端差異。
(7)如何捕獲 app 的 onError。由于 onError 并不是完整意義的生命周期,所以只提供一個(gè)捕獲錯(cuò)誤的方法,在 app 的根組件上添加名為 onError 的回調(diào)函數(shù)即可。如下:
export default { // 只有 app 才會(huì)有 onLaunch 的生命周期 onLaunch () { // … }, // 捕獲 app error onError (err) { console.log(err) }}
二、使用
通過(guò) Vue.js 命令行工具 vue-cli,你只需在終端窗口輸入幾條簡(jiǎn)單命令,即可快速創(chuàng)建和啟動(dòng)一個(gè)帶熱重載、保存時(shí)靜態(tài)檢查、內(nèi)置代碼構(gòu)建功能的小程序項(xiàng)目:
npm install –global vue-cli//全局安裝vue-cli,如果你已安裝@vue/cli,你需要拉取2.x模板:npm install -g @vue/cli-intvue init mpvue/mpvue-quickstart <project name>//創(chuàng)建一個(gè)基于 mpvue-quickstart 模板的新項(xiàng)目cd my-project //進(jìn)入項(xiàng)目目錄npm install //安裝依賴npm run dev //啟動(dòng)構(gòu)建
如果使用vue cli 3先拉取 2.x 模板(詳情參考本人博客:https://my.oschina.net/wangnian/blog/2051369):
然后:安裝npm包,運(yùn)行
本文出處:王念博客。? 著作權(quán)歸作者所有;如有侵權(quán),請(qǐng)聯(lián)系刪除。
版權(quán)聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻(xiàn),該文觀點(diǎn)僅代表作者本人。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如發(fā)現(xiàn)本站有涉嫌抄襲侵權(quán)/違法違規(guī)的內(nèi)容, 請(qǐng)發(fā)送郵件至 舉報(bào),一經(jīng)查實(shí),本站將立刻刪除。