微信小程序mpvue框架總結

原理架構

JSBridge

做爲native 與 JS 之間相互通訊的橋樑
JS部分(bridge): 在JS環境中注入 bridge 的實現代碼,包含了協議的拼裝/發送/參數池/回調池等一些基礎功能。
Native部分(SDK): 在客戶端中 bridge 的功能映射代碼,實現了URL攔截與解析/環境信息的注入/通用功能映射等功能。css

邏輯層與視圖層

一、邏輯層負責計算邏輯處理
二、視圖層負責頁面展現
數據變動驅動視圖更新;視圖交互觸發事件,事件響應函數修改數據再次觸發視圖更新(用戶交互,觸發邏輯計算,最後由視圖更新展現)html

原理

vue - data -> 小程序
vue <- 事件響應 - 小程序vue

一、生命週期關聯:在小程序上觸發數據更新,由vue處理,vue處理完後同步到小程序
爲實現數據同步,mpvue 修改了 Vue.js runtime 實現,在 Vue.js 的生命週期中增長了更新小程序數據的邏輯。
二、事件代理機制:用戶交互觸發的數據更新經過事件代理機制完成,在小程序觸發的事件代理到vue的method上
在小程序組件節點上觸發事件後,找到虛擬 DOM 上對應的節點,觸發對應的事件;另外一方面,Vue.js 事件響應若是觸發了數據更新,其生命週期函數更新將自動觸發,在此函數上同步更新小程序數據,數據同步也就實現了node

Vue代碼
一、將小程序頁面編寫爲 Vue.js 實現
二、以 Vue.js 開發規範實現父子組件關聯git

小程序代碼
一、以小程序開發規範編寫視圖層模板
二、配置生命週期函數,關聯數據更新調用
三、將 Vue.js 數據映射爲小程序數據模型github

並在此基礎上,附加以下機制
一、Vue.js 實例與小程序 Page 實例創建關聯
二、小程序和 Vue.js 生命週期創建映射關係,能在小程序生命週期中觸發 Vue.js 生命週期
三、小程序事件創建代理機制,在事件代理函數中觸發與之對應的 Vue.js 組件事件響應vue-cli

Vue.js 視圖層渲染由 render 方法完成,同時在內存中維護着一份虛擬 DOM,mpvue 無需使用 Vue.js 完成視圖層渲染,經過改造 render 方法,禁止視圖層渲染;在 Vue runtime 時,添加平臺 mpvuenpm

事件代理機制

一、在 mpvue 生成的 wxml 文件中,全部的事件都被 handleProxy 的函數接管,在 handleProxy 進行處理後再去調用咱們寫的真正的事件處理函數。這個方法在initMp時,做爲小程序Page構造函數的一個選項,從而能夠在wxml中被正確調用
二、handleProxy將小程序的event對象傳給handleProxyWithVue函數進行進一步處理
三、handleProxyWithVue 的做用json

  1. 從根實例開始,根據comkey找出事件處理函數所在的mpvue實例(getVm)
  2. 經過遍歷找到的vm的vnode,結合eventid找到小程序事件對應的真實的事件處理函數(getHandle)
  3. 將小程序的event對象包裝爲mpvue的event對象(getWebEventByMP),並添加了preventDefault和stopPropagation方法
  4. 將包裝後的event對象傳給真實的處理函數進行調用。

(生成的wxml中綁定事件的節點都有data-comkey和data-eventid屬性,在一個事件觸發時,它們是被用來尋找事件對應的vm實例和對應的事件處理函數的)小程序

生命週期

微信小程序:

一、App對象,主要有onLaunch, onShow和onHide
二、Page對象,主要有onLoad, onShow, onReady, onHide和onUnload

Vue的生命週期主要體如今8個鉤子:

beforeCreate, created, beforeMount, mounted, beforeUpdate, updated, beforeDestroy, destroyed

vue & mpvue 生命週期

mpvue 生命週期圖

mpvue 生命週期

vuw & mpvue 生命週期對比圖

vuw & mpvue 生命週期對比圖

過程

app啓動:
app-beforeCreate -> app-created -> app-onlaunch -> app-beforeMount -> app-mounted -> app-onShow

進入頁面,更新操做:
page beforeCreate -> page created -> page onLoad -> page onShow -> page onReady -> page beforeMount -> component beforeCreate -> component created -> component onLoad -> component onReady -> component beforeMount -> component mounted -> page mounted

返回(隱藏),沒有觸發destroy:
page onUnload -> component onUnload

測試

page A、B(page tab)、C、D(page tab) (c 是 A 的子組件)
A -> B -> A (按鈕跳轉)
A -> B (點擊左上角返回鍵)

一、App啓動
app-beforeCreate.....
app-created...
app-onlaunch...
app-beforeMount.....
app-mounted.....
app-onShow....
A-beforeCreate.....
A-created....
B-beforeCreate.....
B-created.....
D-beforeCreate.....
D-created.....

二、進入 page A
A-onLoad....
A-onShow....
A-onReady.....
A-beforeMount.....
C-beforeCreate.....
C-created.....
C-onLoad....
C-onReady.....
C-beforeMount.....
C-mounted.....
A-mounted.....

三、離開page A
A-onUnload....
C-onUnload....

四、進入page B
B-onLoad....
B-onShow....
B-onReady.....
B-beforeMount.....
B-mounted.....
B-beforeUpdate..... // 更新
B-updated.....

五、離開page B
B-onHide.....

六、從新進入page A(switchTab)
A-onLoad....
C-onLoad....
A-onShow....
C-onShow....
A-onReady.....
C-onReady.....
A-beforeMount.....
A-beforeUpdate.....
A-mounted.....
C-beforeUpdate.....
C-updated.....

七、經過返回鍵返回 page B
A-onUnload....
C-onUnload....
B-onShow....

建立項目

# 安裝 vue-cli
$ npm install --global vue-cli
# 根據模板項目建立本地項目,目前爲內網地址
$ vue init mpvue/mpvue-quickstart my-project
# 安裝依賴和啓動自動構建
$ cd my-project
$ npm install
# 如今支持微信wx、頭條tt、支付寶my、百度swan,運行該命令生成dist文件夾,即小程序
$ npm run dev

目錄結構

├── build                  編譯配置
├── config                 編譯配置
├── dist                   小程序運行代碼目錄(該目錄由編譯生成)
├── `node_modules`           
├── src                    開發目錄
|   ├── components         組件目錄
|   |   ├── a.vue      組件a
|   |   └── b.vue      組件b
|   ├── pages              頁面目錄
|   |   ├── index          index頁面(默認會在src/main.js主入口生成pages配置,路徑爲pages/index/main)
            ├── index.vue  由其入口文件編譯main.js後,生成index/main.js、index/main.wxml和index/main.wxss文件
            ├── main.js     頁面默認入口文件(config屬性會編譯爲頁面配置文件index/main.json)
|   |   └── other           other頁面(默認會在src/main.js主入口生成pages配置,路徑爲pages/other/main)
            ├── index.vue  由其入口文件編譯main.js後,生成other/main.js、other/main.wxml和other/main.wxss文件
            ├── main.js    頁面默認入口文件(config屬性會編譯爲頁面配置文件other/main.json)
|   └── main.js            小程序配置項(全局數據、樣式、聲明鉤子等;經build後,會在dist目錄下生成app.js、app.json和app.wxss文件)
└── static                 靜態文件,會直接被複制到dist/下
└── package.json           項目的package配置
└── project.config.json    小程序開發工具的配置

項目demo

本身寫的demo,在以前原生微信小程序的基礎上,使用 mpvue 重構了電影模塊:
mpvue-play

注意

如下是一些本身在寫demo時,踩過的坑或是一些須要注意的點(尤爲對習慣了vue的童學),具體也可參見mpvue文檔
一、onShow 代替 mounted:從一個頁面返回到前一頁面時,mounted不會再次被調用,由於頁面沒有被銷燬,於是不須要從新掛載
onLoad 代替 created: 啓動項目時,全部頁面的beforeCreatecreated都已調用,而且進入頁面時,不會再調用beforeCreatecreated
雖然建議儘可能不要使用小程序中的生命週期的鉤子函數

二、小程序不支持路由,所以,路由跳轉使用小程序的頁面導航api代替
this.$router.push --> wx.navigateTo() //進入子頁面
this.$router.replace --> wx.reLaunch()//打開新頁面

三、微信小程序的頁面的 query 參數是經過 onLoad 獲取的,mpvue 對此進行了優化,直接經過 this.$root.$mp.query 獲取相應的參數數據

四、小程序裏全部的 BOM/DOM 都不能用,所以v-html、v-text不能用

五、圖片 src="{{}}" => :src="",才能生效

六、不支持部分複雜的 JavaScript 渲染表達式,mpvue會把 template 中的 {{}} 雙花括號的部分,直接編碼到 wxml 文件中,因爲微信小程序的能力限制(數據綁定),因此沒法支持複雜的 JavaScript 表達式。建議使用computed
目前可使用的有 + - * % ?: ! == === > < [] .,剩下的還待完善。

七、不支持filter過濾器,由於小程序wxml不支持

八、列表渲染須要注意一點,嵌套列表渲染,必須指定不一樣的索引 :key=""

九、不支持在 template 內使用 methods 中的函數,即<div>{{handleFn()}}</div>

十、獲取當前頁面地址
this.$route.fullPath --> getCurrentPages()[0].route

十一、不支持本地圖片用做背景圖,可使用網絡圖片、或者base64,或者使用img、image標籤

十二、上拉加載/下拉刷新,選用小程序的全局api; scroll-view中沒法使用

1三、不支持css媒體查詢,css樣式避免標籤選擇器,不易於維護,儘可能使用類選擇器

1四、CSS樣式導入,使用 @import url("")

1五、暫不支持在組件上使用 Class 與 Style 綁定

參考:
mpvue文檔
用Vue.js開發微信小程序:開源框架mpvue解析
mpvue小程序開發 - 生命週期梳理
美團小程序框架--mpvue入坑指南
mpVue的使用小技巧之跳轉與傳參
小程序開發框架WePY與mpvue
px2rpx-loader使用和源碼分析

相關文章
相關標籤/搜索