使用手冊(cè)
mpvue?繼承自?Vue.js辆脸,其技術(shù)規(guī)范和語(yǔ)法特點(diǎn)與?Vue.js?保持一致话原。
本文檔適用于有一定?Vue.js?使用經(jīng)驗(yàn)的開(kāi)發(fā)者倚聚。我們默認(rèn)你已經(jīng)掌握?Vue.js?技術(shù)體系线衫,如果你是新手,你可能需要先熟悉?Vue.js 官方文檔惑折。
#五分鐘教程
通過(guò)?Vue.js?命令行工具?vue-cli授账,你只需在終端窗口輸入幾條簡(jiǎn)單命令,即可快速創(chuàng)建和啟動(dòng)一個(gè)帶熱重載惨驶、保存時(shí)靜態(tài)檢查白热、內(nèi)置代碼構(gòu)建功能的小程序項(xiàng)目:
# 全局安裝 vue-cli$npminstall--global vue-cli# 創(chuàng)建一個(gè)基于 mpvue-quickstart 模板的新項(xiàng)目$ vue init mpvue/mpvue-quickstart my-project# 安裝依賴(lài)$cdmy-project$npminstall# 啟動(dòng)構(gòu)建$npmrun dev
接下來(lái),你只需要啟動(dòng)微信開(kāi)發(fā)者工具粗卜,引入項(xiàng)目即可預(yù)覽到你的第一個(gè)?mpvue?小程序屋确。
#框架原理
mpvue?保留了 vue.runtime 核心方法,無(wú)縫繼承了?Vue.js?的基礎(chǔ)能力
mpvue-template-compiler?提供了將 vue 的模板語(yǔ)法轉(zhuǎn)換到小程序的 wxml 語(yǔ)法的能力
修改了 vue 的建構(gòu)配置续扔,使之構(gòu)建出符合小程序項(xiàng)目結(jié)構(gòu)的代碼格式: json/wxml/wxss/js 文件
#Vue 實(shí)例
支持?官方文檔:Vue 實(shí)例攻臀,同時(shí)我們做了一些修改,來(lái)適應(yīng)小程序的獨(dú)特加載邏輯纱昧。
#實(shí)例生命周期
同 vue刨啸,不同的是我們會(huì)在小程序 onReady 后苍姜,再去觸發(fā) vue mounted 生命周期只嚣,詳細(xì)的 vue 生命周期文檔請(qǐng)看生命周期鉤子
beforeCreate
created
beforeMount
mounted
beforeUpdate
updated
activated
deactivated
beforeDestroy
destroyed
除了 Vue 本身的生命周期外瞄沙,mpvue 還兼容了小程序生命周期忘嫉,這部分生命周期鉤子的來(lái)源于微信小程序的 Page, 除特殊情況外挂洛,不建議使用小程序的生命周期鉤子佩谣。
app 部分:
onLaunch凡怎,初始化
onShow悉稠,當(dāng)小程序啟動(dòng)宫蛆,或從后臺(tái)進(jìn)入前臺(tái)顯示
onHide,當(dāng)小程序從前臺(tái)進(jìn)入后臺(tái)
page 部分:
onLoad偎球,監(jiān)聽(tīng)頁(yè)面加載
onShow洒扎,監(jiān)聽(tīng)頁(yè)面顯示
onReady,監(jiān)聽(tīng)頁(yè)面初次渲染完成
onHide衰絮,監(jiān)聽(tīng)頁(yè)面隱藏
onUnload,監(jiān)聽(tīng)頁(yè)面卸載
onPullDownRefresh磷醋,監(jiān)聽(tīng)用戶(hù)下拉動(dòng)作
onReachBottom猫牡,頁(yè)面上拉觸底事件的處理函數(shù)
onShareAppMessage,用戶(hù)點(diǎn)擊右上角分享
onPageScroll邓线,頁(yè)面滾動(dòng)
onTabItemTap, 當(dāng)前是 tab 頁(yè)時(shí)淌友,點(diǎn)擊 tab 時(shí)觸發(fā) (mpvue 0.0.16 支持)
用法示例:
newVue({data:{a:1},created(){// `this` 指向 vm 實(shí)例console.log('a is: '+this.a)},onShow(){// `this` 指向 vm 實(shí)例console.log('a is: '+this.a,'小程序觸發(fā)的 onshow')}})// => "a is: 1"
注意點(diǎn):
不要在選項(xiàng)屬性或回調(diào)上使用箭頭函數(shù)煌恢,比如?created: () => console.log(this.a)?或?vm.$watch('a', newValue => this.myMethod())。因?yàn)榧^函數(shù)是和父級(jí)上下文綁定在一起的震庭,this?不會(huì)是如你做預(yù)期的 Vue 實(shí)例瑰抵,且?this.a?或?this.myMethod?也會(huì)是未定義的。
微信小程序的頁(yè)面的?query?參數(shù)是通過(guò)?onLoad?獲取的器联,mpvue 對(duì)此進(jìn)行了優(yōu)化二汛,直接通過(guò)?this.$root.$mp.query?獲取相應(yīng)的參數(shù)數(shù)據(jù),其調(diào)用需要在?onLoad?生命周期觸發(fā)之后使用拨拓,比如?onShow?等肴颊,具體生命周期調(diào)用順序,見(jiàn)下圖渣磷。
#生命周期圖示
你不需要立馬弄明白所有的東西婿着,不過(guò)隨著你的不斷學(xué)習(xí)和使用,它的參考價(jià)值會(huì)越來(lái)越高醋界。
生命周期的調(diào)用關(guān)系和順序圖竟宋。
#模板語(yǔ)法
幾乎全支持?官方文檔:模板語(yǔ)法,下面講下不支持的情況形纺。
#不支持?純-HTML
小程序里所有的 BOM/DOM 都不能用袜硫,也就是說(shuō)?v-html?指令不能用。
#不支持部分復(fù)雜的 JavaScript 渲染表達(dá)式
我們會(huì)把 template 中的?{{}}?雙花括號(hào)的部分挡篓,直接編碼到 wxml 文件中婉陷,由于微信小程序的能力限制(數(shù)據(jù)綁定),所以無(wú)法支持復(fù)雜的 JavaScript 表達(dá)式官研。
目前可以使用的有?+ - * % ?: ! == === > < [] .秽澳,剩下的還待完善。
<!-- 這種就不支持戏羽,建議寫(xiě) computed --><p>{{ message.split('').reverse().join('') }}</p><!-- 但寫(xiě)在 @event 里面的表達(dá)式是都支持的担神,因?yàn)檫@部分的計(jì)算放在了 vdom 里面 --><ul><liv-for="item in list"><div@click="clickHandle(item, index, $event)">{{ item.value }}</p></li></ul>
#不支持過(guò)濾器
渲染部分會(huì)轉(zhuǎn)成 wxml ,wxml 不支持過(guò)濾器始花,所以這部分功能不支持妄讯。
#計(jì)算屬性
支持?官方文檔:計(jì)算屬性。
#不支持函數(shù)
不支持在 template 內(nèi)使用 methods 中的函數(shù)酷宵。
#Class 與 Style 綁定
為節(jié)約性能亥贸,我們將 Class 與 Style 的表達(dá)式通過(guò) compiler 硬編碼到 wxml 中,支持語(yǔ)法和轉(zhuǎn)換效果如下:
class 支持的語(yǔ)法:
<p :class="{ active: isActive }">111</p>
<p class="static" v-bind:class="{ active: isActive, 'text-danger': hasError }">222</p>
<p class="static" :class="[activeClass, errorClass]">333</p>
<p class="static" v-bind:class="[isActive ? activeClass : '', errorClass]">444</p>
<p class="static" v-bind:class="[{ active: isActive }, errorClass]">555</p>
將分別被轉(zhuǎn)換成:
<view class="_p {{[isActive ? 'active' : '']}}">111</view>
<view class="_p static {{[isActive ? 'active' : '', hasError ? 'text-danger' : '']}}">222</view>
<view class="_p static {{[activeClass, errorClass]}}">333</view>
<view class="_p static {{[isActive ? activeClass : '', errorClass]}}">444</view>
<view class="_p static {{[[isActive ? 'active' : ''], errorClass]}}">555</view>
style 支持的語(yǔ)法:
<p v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }">666</p>
<p v-bind:style="[{ color: activeColor, fontSize: fontSize + 'px' }]">777</p>
將分別被轉(zhuǎn)換成:
<view class="_p" style=" {{'color:' + activeColor + ';' + 'font-size:' + fontSize + 'px' + ';'}}">666</view>
<view class="_p" style=" {{'color:' + activeColor + ';' + 'font-size:' + fontSize + 'px' + ';'}}">777</view>
不支持?官方文檔:Class 與 Style 綁定?中的?classObject?和?styleObject?語(yǔ)法浇垦。
最佳實(shí)踐見(jiàn)上文支持的語(yǔ)法炕置,從性能考慮,建議不要過(guò)度依賴(lài)此。
此外還可以用 computed 方法生成 class 或者 style 字符串朴摊,插入到頁(yè)面中默垄,舉例說(shuō)明:
<template><!-- 支持 --><divclass="container":class="computedClassStr"></div><divclass="container":class="{active: isActive}"></div><!-- 不支持 --><divclass="container":class="computedClassObject"></div></template><script>exportdefault{data(){return{isActive:true}},computed:{computedClassStr(){returnthis.isActive?'active':''},computedClassObject(){return{active:this.isActive}}}}</script>
#用在組件上
暫不支持在組件上使用 Class 與 Style 綁定
#條件渲染
全支持?官方文檔:條件渲染
#列表渲染
全支持?官方文檔:列表渲染
只是需要注意一點(diǎn),嵌套列表渲染甚纲,必須指定不同的索引口锭!
示例:
<!-- 在這種嵌套循環(huán)的時(shí)候, index 和 itemIndex 這種索引是必須指定介杆,且別名不能相同鹃操,正確的寫(xiě)法如下 --><template><ulv-for="(card, index) in list"><liv-for="(item, itemIndex) in card">{{item.value}}</li></ul></template>
#事件處理器
幾乎全支持啦?官方文檔:事件處理器
我們引入了 Vue.js 的虛擬 DOM ,在前文模版中綁定的事件會(huì)被掛在到 vnode 上这溅,同時(shí)我們的 compiler 在 wxml 上綁定了小程序的事件组民,并做了相應(yīng)的映射,所以你在真實(shí)點(diǎn)擊的時(shí)候通過(guò) runtime 中?handleProxy?通過(guò)事件類(lèi)型分發(fā)到 vnode 的事件上悲靴,同 Vue 在 WEB 的機(jī)制一樣臭胜,所以可以做到無(wú)損支持。同時(shí)還順便支持了自定義事件和?$emit?機(jī)制癞尚。
// 事件映射表耸三,左側(cè)為 WEB 事件,右側(cè)為 小程序 對(duì)應(yīng)事件{click:'tap',touchstart:'touchstart',touchmove:'touchmove',touchcancel:'touchcancel',touchend:'touchend',tap:'tap',longtap:'longtap',input:'input',change:'change',submit:'submit',blur:'blur',focus:'focus',reset:'reset',confirm:'confirm',columnchange:'columnchange',linechange:'linechange',error:'error',scrolltoupper:'scrolltoupper',scrolltolower:'scrolltolower',scroll:'scroll'}
在?input?和?textarea?中?change?事件會(huì)被轉(zhuǎn)為?blur?事件浇揩。
踩坑注意:
列表中沒(méi)有的原生事件也可以使用例如 bindregionchange 事件直接在 dom 上將bind改為@?@regionchange,同時(shí)這個(gè)事件也非常特殊仪壮,它的 event type 有 begin 和 end 兩個(gè),導(dǎo)致我們無(wú)法在handleProxy?中區(qū)分到底是什么事件胳徽,所以你在監(jiān)聽(tīng)此類(lèi)事件的時(shí)候同時(shí)監(jiān)聽(tīng)事件名和事件類(lèi)型既?<map @regionchange="functionName" @end="functionName" @begin="functionName"><map>
小程序能力所致积锅,bind 和 catch 事件同時(shí)綁定時(shí)候,只會(huì)觸發(fā) bind ,catch 不會(huì)被觸發(fā)养盗,要避免踩坑缚陷。
事件修飾符
.stop?的使用會(huì)阻止冒泡,但是同時(shí)綁定了一個(gè)非冒泡事件往核,會(huì)導(dǎo)致該元素上的 catchEventName 失效箫爷!
.prevent?可以直接干掉,因?yàn)樾〕绦蚶餂](méi)有什么默認(rèn)事件聂儒,比如submit并不會(huì)跳轉(zhuǎn)頁(yè)面
.capture?支持?1.0.9
.self?沒(méi)有可以判斷的標(biāo)識(shí)
.once?也不能做虎锚,因?yàn)樾〕绦驔](méi)有 removeEventListener, 雖然可以直接在 handleProxy 中處理,但非常的不優(yōu)雅衩婚,違背了原意窜护,暫不考慮
其他 鍵值修飾符 等在小程序中壓根沒(méi)鍵盤(pán),所以谅猾。柄慰。鳍悠。
#表單控件綁定
幾乎全支持?官方文檔:表單控件綁定税娜,不支持的還沒(méi)測(cè)出來(lái)坐搔,之所以說(shuō)幾乎,是因?yàn)?WEB 表單這么復(fù)雜敬矩,誰(shuí)特么知道會(huì)出什么奇怪的特性概行。
建議開(kāi)發(fā)過(guò)程中直接使用?微信小程序:表單組件?。用法示例:
<template><div><picker@change="bindPickerChange":value="index":range="array"><viewclass="picker">當(dāng)前選擇:{{array[index]}}</view></picker></div></template><script>exportdefault{data(){return{index:0,array:['A','B','C']}},methods:{bindPickerChange(e){console.log(e)}}}</script>
表單元素 radio 用 radio-group 組件進(jìn)行代替
<template><div><radio-groupclass="radio-group"@change="radioChange"><labelclass="radio"v-for="(item, index) in items":key="item.name"><radio:value="item.name":checked="item.checked"/>{{item.value}}</label></radio-group></div></template><script>exportdefault{data(){return{items:[{name:'USA',value:'美國(guó)'},{name:'CHN',value:'中國(guó)',checked:'true'},{name:'BRA',value:'巴西'},{name:'JPN',value:'日本'},{name:'ENG',value:'英國(guó)'},{name:'TUR',value:'法國(guó)'}]}},methods:{radioChange(e){console.log('radio發(fā)生change事件弧岳,攜帶value值為:',e.target.value)}}}</script>
#組件
#Vue 組件
組件是整個(gè) Vue.js 中最復(fù)雜的部分凳忙,當(dāng)然要支持?官方文檔:組件?。
**有且只能使用單文件組件(.vue 組件)的形式進(jìn)行支持禽炬。**其他的諸如:動(dòng)態(tài)組件涧卵,自定義 render,和<script type="text/x-template">?字符串模版等都不支持腹尖。原因很簡(jiǎn)單柳恐,因?yàn)槲覀円A(yù)編譯出 wxml。
如果未來(lái)小程序支持了動(dòng)態(tài)增刪改查 wxml 節(jié)點(diǎn)信息热幔,那我們就能做到全支持乐设。
詳細(xì)的不支持列表:
暫不支持在組件引用時(shí),在組件上定義 click 等原生事件绎巨、v-show(可用 v-if 代替)和 class style 等樣式屬性(例:<card class="class-name"> </card>?樣式是不會(huì)生效的)近尚,因?yàn)榫幾g到 wxml,小程序不會(huì)生成節(jié)點(diǎn)场勤,建議寫(xiě)在內(nèi)部頂級(jí)元素上戈锻。
Slot(scoped 暫時(shí)還沒(méi)做支持)
動(dòng)態(tài)組件
異步組件
inline-template
X-Templates
keep-alive
transition
class
style
#小程序組件
mpvue 可以支持小程序的原生組件,比如:?picker,map?等和媳,需要注意的是原生組件上的事件綁定格遭,需要以?vue?的事件綁定語(yǔ)法來(lái)綁定,如?bindchange="eventName"?事件窗价,需要寫(xiě)成?@change="eventName"
示例代碼:
<pickermode="date":value="date"start="2015-09-01"end="2017-09-01"@change="bindDateChange"><viewclass="picker">當(dāng)前選擇: {{date}}</view></picker>
#TypeScript支持
目前mpvue-loader是可以支持TypeScript選項(xiàng)的如庭,配置方法在此。具體Demo可以見(jiàn)mpvue-ts-demo
#最佳實(shí)踐
1. 精簡(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è)面非嘲辛铮卡頓开瞭。
2. 優(yōu)化長(zhǎng)列表性能
一般情況下這種頁(yè)面會(huì)有大量的數(shù)據(jù)懒震,除了遵從上面的建議外還有額外的建議。
避免在 v-for 中嵌套子組件嗤详,這樣可以?xún)?yōu)化大部分部分 setData 時(shí)的冗余數(shù)據(jù)个扰。
通過(guò)實(shí)踐發(fā)現(xiàn) wx:if 和 hidden 的優(yōu)化肉眼不可見(jiàn),所以或許可以試試直接通過(guò)樣式 display 來(lái)展示和隱藏葱色。
如果列表過(guò)長(zhǎng)递宅,強(qiáng)烈建議產(chǎn)品思考更好的展示形態(tài)。比如只展示熱門(mén)苍狰,多余的折疊等形式办龄。
注:我們對(duì)其進(jìn)行了專(zhuān)門(mén)優(yōu)化,最佳實(shí)踐時(shí)和原生小程序代碼的性能相差無(wú)幾淋昭。
3. 合理使用雙向綁定?mpvue?建議使用?v-model.lazy?綁定方式以?xún)?yōu)化性能俐填,此外?v-model?在老基礎(chǔ)庫(kù)下輸入框輸入時(shí)可能存在光標(biāo)重設(shè)的問(wèn)題。
4. 謹(jǐn)慎選擇直接使用小程序的 API?如果你有小程序和H5復(fù)用代碼的需要翔忽,業(yè)務(wù)代碼需要保持對(duì) WEB?Vue.js?的兼容性英融。此時(shí)我們不建議在代碼中直接調(diào)用小程序API,更好的選擇是通過(guò)橋接適配層屏蔽兩端差異呀打。
#常見(jiàn)問(wèn)題
1. 如何獲取小程序在 page onLoad 時(shí)候傳遞的 options
在所有 頁(yè)面 的組件內(nèi)可以通過(guò)?this.$root.$mp.query?進(jìn)行獲取矢赁。
2. 如何獲取小程序在 app onLaunch/onShow 時(shí)候傳遞的 options
在所有的組件內(nèi)可以通過(guò)?this.$root.$mp.appOptions?進(jìn)行獲取。
3. 如何捕獲 app 的 onError
由于 onError 并不是完整意義的生命周期贬丛,所以只提供一個(gè)捕獲錯(cuò)誤的方法撩银,在 app 的根組件上添加名為 onError 的回調(diào)函數(shù)即可。如下:
exportdefault{// 只有 app 才會(huì)有 onLaunch 的生命周期onLaunch(){// ...},// 捕獲 app erroronError(err){console.log(err)}}
#mpvue 框架使用場(chǎng)景匯總
mpvue?作為一個(gè)前端開(kāi)發(fā)框架豺憔,提供了一整套解決方案额获。但開(kāi)發(fā)者面臨的實(shí)際情況可能更加復(fù)雜,我們整理了?mpvue?可能的使用場(chǎng)景恭应,在這些場(chǎng)景下抄邀,我們?yōu)槟闾峁┝艘恍┙ㄗh。
首先昼榛,mpvue?小程序框架包含如下內(nèi)容:
運(yùn)行時(shí)JS SDK
初始化模板項(xiàng)目(包含推薦的目錄結(jié)構(gòu)境肾,webpack構(gòu)建,代碼檢查配置等)
項(xiàng)目構(gòu)建所需的 npm 依賴(lài)(已經(jīng)包含在項(xiàng)目模板中胆屿,無(wú)需手動(dòng)引入)
#開(kāi)發(fā)者可能會(huì)面對(duì)的四種典型場(chǎng)景
單獨(dú)以?mpvue?框架構(gòu)建小程序
mpvue?框架為主奥喻,同時(shí)使用其它框架(原生開(kāi)發(fā)方式或wepy等)
已經(jīng)使用其它框架,引入?mpvue?做部分模塊的開(kāi)發(fā)
只使用?mpvue?的 JS SDK非迹,自定義構(gòu)建策略
針對(duì)上述不同場(chǎng)景环鲤,mpvue?框架需要提供的方案和建議如下
單獨(dú)以?mpvue?框架構(gòu)建小程序
推薦的方式,無(wú)需額外支持憎兽。通過(guò)框架提供的項(xiàng)目初始化工具初始化項(xiàng)目即可冷离,已經(jīng)包含完整的構(gòu)建策略吵冒,代碼組織方式等.
mpvue?框架為主,同時(shí)使用其它框架(原生開(kāi)發(fā)方式或wepy等)
第三方框架和?mpvue?做分塊構(gòu)建西剥”云埽可能的方案是:不同框架各自的構(gòu)建策略做好邊界分離,最終通過(guò)單一入口聚合到一起蔫耽〗嵋或者更簡(jiǎn)單的留夜,拆成多個(gè)子項(xiàng)目匙铡,最終輸出到同一目錄,目標(biāo)代碼符合小程序規(guī)范即可碍粥。
已經(jīng)使用其它框架鳖眼,引入?mpvue?做部分模塊的開(kāi)發(fā)
mpvue?提供輕量的模塊構(gòu)建工具支持部分構(gòu)建。對(duì)已有小程序項(xiàng)目接入?mpvue?來(lái)說(shuō)嚼摩,漸進(jìn)的方式會(huì)是樂(lè)于接受的钦讳,可以先讓一部分功能通過(guò)?mpvue?編寫(xiě)。此類(lèi)場(chǎng)景枕面,不再適合通過(guò)模板項(xiàng)目初始化項(xiàng)目結(jié)構(gòu)愿卒,開(kāi)發(fā)者可以參考模板項(xiàng)目中的代碼編寫(xiě)方式,通過(guò)我們單獨(dú)準(zhǔn)備的構(gòu)建工具潮秘,定制好構(gòu)建任務(wù)即可琼开。
只使用?mpvue?的 JS SDK,自定義構(gòu)建策略
需要開(kāi)發(fā)者自定義 webpack 構(gòu)建策略枕荞。 框架本身不建議開(kāi)發(fā)者這么使用柜候。但對(duì)于高階的開(kāi)發(fā)者,這是可能的方案躏精。此時(shí)渣刷,開(kāi)發(fā)者可以參考我們模板項(xiàng)目中的構(gòu)建策略即可,我們目前只提供 webpack 構(gòu)建方案矗烛。對(duì)于其它構(gòu)建辅柴,我們暫不支持。
轉(zhuǎn)載于:http://mpvue.com/mpvue/