小程式第三方框架對比 ( wepy / mpvue / taro )

李初五發表於2019-01-26

###
眾所周知如今市面上端的形態多種多樣,手機Web、ReactNative、微信小程式, 支付寶小程式, 快應用等,每一端都是巨大的流量入口,當業務要求同時在不同的端都要求有所表現的時候,針對不同的端去編寫多套程式碼的成本顯然非常高,這時候只編寫一套程式碼就能夠適配到多端的能力就顯得極為需要。但面對目前市面上成熟的小程式第三方框架如何針對自己的需求進行選擇也是一個麻煩事,本文針對當前市面上的三大轉譯框架進行一個綜合對比,希望能對大家的技術選擇有所幫助,如有哪裡不妥的地方希望指正;

小程式開發有哪些痛點?

  • 頻繁呼叫 setData及 setData過程中頁面跳閃

  • 元件化支援能力太弱(幾乎沒有)

  • 不能使用 less、scss 等預編譯器

  • request 併發次數限制

為什麼使用第三方框架?

  • 只要熟悉vue或react即可快速上手,學習成本低
  • 一套程式碼可在多端編譯執行(微信,支付寶,h5,RN) 支付寶小程式暫不完善
  • 元件化開發,完美解決元件隔離,元件巢狀,元件通訊等問題
  • 支援使用第三方 npm 資源
  • 使小程式可支援 Promise,解決回撥煩惱
  • 可使用 Generator Fu-nction / Class / Async Function 等特性,提升開發效率
  • 對小程式本身的優化,如生命週期的補充,效能的優化等等
  • 支援樣式編譯器: Scss/Less,模板編譯器,程式碼編譯器:Babel/Typescript。

第三方框架對比 wepy mpvue taro

在這裡我通過對目前已開源的三種常用小程式框架做一個綜合對比, 還有一個叫nanchi的基於react的小程式轉譯框架,由於沒來的及研究暫不做比較;

騰訊團隊開源的一款類vue語法規範的小程式框架,借鑑了Vue的語法風格和功能特性,支援了Vue的諸多特徵,比如父子元件、元件之間的通訊、computed屬性計算、wathcer監聽器、props傳值、slot槽分發,還有很多高階的特徵支援:Mixin混合、攔截器等;WePY釋出的第一個版本是2016年12月份,也就是小程式剛剛推出的時候,到目前為止,WePY已經發布了52個版本, 最新版本為1.7.2;

美團團隊開源的一款使用 Vue.js 開發微信小程式的前端框架。使用此框架,開發者將得到完整的 Vue.js 開發體驗,同時為 H5 和小程式提供了程式碼複用的能力。mpvue在釋出後的幾天間獲得2.7k的star,上升速度飛起,截至目前為止已經有13.7k的star;

京東凹凸實驗室開源的一款使用 React.js 開發微信小程式的前端框架。它採用與 React 一致的元件化思想,元件生命週期與 React 保持一致,同時支援使用 JSX 語法,讓程式碼具有更豐富的表現力,使用 Taro 進行開發可以獲得和 React 一致的開發體驗。,同時因為使用了react的原因所以除了能編譯h5, 小程式外還可以編譯為ReactNative;

小程式第三方框架對比 ( wepy / mpvue / taro )

小程式第三方框架對比 ( wepy / mpvue / taro )

生命週期

同為vue規範的mpvue和wepy的生命週期和各種方法不盡相同

wepy

wepy生命週期基本與原生小程式相同,再此基礎上糅合了一些vue的特性; 對於WePY中的methods屬性,因為與Vue中的使用習慣不一致,非常容易造成誤解,這裡需要特別強調一下:WePY中的methods屬性只能宣告頁面wxml標籤的bind、catch事件,不能宣告自定義方法,這與Vue中的用法是不一致的。   `import wepy from 'wepy';

export default class MyPage extends wepy.page { // export default class MyComponent extends wepy.component { customData = {} // 自定義資料

customFunction () {}  //自定義方法

onLoad () {}  // 在Page和Component共用的生命週期函式

onShow () {}  // 只在Page中存在的頁面生命週期函式

config = {};  // 只在Page例項中存在的配置資料,對應於原生的page.json檔案

data = {};  // 頁面所需資料均需在這裡宣告,可用於模板資料繫結

components = {};  // 宣告頁面中所引用的元件,或宣告元件中所引用的子元件

mixins = [];  // 宣告頁面所引用的Mixin例項

computed = {};  // 宣告計算屬性(詳見後文介紹)

watch = {};  // 宣告資料watcher(詳見後文介紹)

methods = {};  // 宣告頁面wxml中標籤的事件處理函式。注意,此處只用於宣告頁面wxml中標籤的bind、catch事件,自定義方法需以自定義方法的方式宣告

events = {};  // 宣告元件之間的事件處理函式
複製程式碼

}`

mpvue

mpvue 除了 Vue 本身的生命週期外,還相容了小程式生命週期,這部分生命週期鉤子的來源於微信小程式的 Page, 除特殊情況外,不建議使用小程式的生命週期 鉤子。

小程式第三方框架對比 ( wepy / mpvue / taro )

簡單示例

小程式第三方框架對比 ( wepy / mpvue / taro )

taro與react生命週期完全相同

小程式第三方框架對比 ( wepy / mpvue / taro )

列表渲染

在列表渲染上三者也分別有不同的應用方法

wepy當需要迴圈渲染WePY元件時(類似於通過wx:for迴圈渲染原生的wxml標籤),必須使用WePY定義的輔助標籤

小程式第三方框架對比 ( wepy / mpvue / taro )

mpvue使用v-for與vue一致,只是需要注意一點,巢狀列表渲染,必須指定不同的索引!

小程式第三方框架對比 ( wepy / mpvue / taro )

taro的列表迴圈用法基本與react相同,有一點需要注意,在 React 中,JSX 是會編譯成普通的 JS 的執行,每一個 JSX 元素,其實會通過 createElement 函式建立成一個 JavaScript 物件(React Element),因此實際上你可以這樣寫程式碼 React 也是完全能渲染的:

小程式第三方框架對比 ( wepy / mpvue / taro )

但是 Taro 中,JSX 會編譯成微信小程式模板字串,因此你不能把 map 函式生成的模板當做一個陣列來處理。當你需要這麼做時,應該先處理需要迴圈的陣列,再用處理好的陣列來呼叫 map 函式。例如上例應該寫成:

小程式第三方框架對比 ( wepy / mpvue / taro )

事件處理

mpvue目前全支援小程式的事件處理器,引入了 Vue.js 的虛擬 DOM ,在前文模版中繫結的事件會被掛在到 vnode 上,同時 compiler 在 wxml 上繫結了小程式的事件,並做了相應的對映,所以你在真實點選的時候通過 runtime 中 handleProxy 通過事件型別分發到 vnode 的事件上,同 Vue 在 WEB 的機制一樣,所以可以做到無損支援。同時還順便支援了自定義事件和 $emit 機制

事件對映表,左側為 WEB 事件,右側為 小程式 對應事件

**click** : 'tap',<br>
**touchstart**: 'touchstart',<br>
**touchmove**: 'touchmove',<br>
**touchcancel**: 'touchcancel',<br>
**touchend**: 'touchend',<br>
**tap**: 'tap',<br>
**longtap**: 'longtap',<br>
**input**: 'input',<br>
**change**: 'change',<br>
**submit**: 'submit',<br>
**blur**: 'blur',<br>
**focus**: 'focus',<br>
**reset**: 'reset',<br>
**confirm**: 'confirm',<br>
**columnchange**: 'columnchange',<br>
**linechange**: 'linechange',<br>
**error**: 'error',<br>
**scrolltoupper**: 'scrolltoupper',<br>
**scrolltolower**: 'scrolltolower',<br>
**scroll**: 'scroll'<br>
複製程式碼

踩坑注意(官方文件):

  • 列表中沒有的原生事件也可以使用例如 bindregionchange 事件直接在 dom 上將bind改為@ @regionchange,同時這個事件也非常特殊,它的 event type 有 begin 和 end 兩個,導致我們無法在handleProxy 中區分到底是什麼事件,所以你在監聽此類事件的時候同時監聽事件名和事件型別既 <map @regionchange="functionName" @end="functionName" @begin="functionName">
  • 小程式能力所致,bind 和 catch 事件同時繫結時候,只會觸發 bind ,catch 不會被觸發,要避免踩坑。
  • 事件修飾符 .stop 的使用會阻止冒泡,但是同時繫結了一個非冒泡事件,會導致該元素上的 catchEventName 失效! .prevent 可以直接幹掉,因為小程式裡沒有什麼預設事件,比如submit並不會跳轉頁面 .capture 支援 1.0.9 .self 沒有可以判斷的標識 .once 也不能做,因為小程式沒有 removeEventListener, 雖然可以直接在 handleProxy 中處理,但非常的不優雅,違背了原意,暫不考慮
  • 其他 鍵值修飾符 等在小程式中壓根沒鍵盤,所以。。。

wepy事件繫結區別於vue,根據原生小程式事件提供了語法優化

繫結事件
bindtap="click" 替換為 @tap="click",
取消冒泡
原catchtap="click"替換為@tap.stop="click"。

捕獲監聽事件
capture-bind:tap="click" 替換為 @tap.capture="click",
中斷捕獲監聽
capture-catch:tap=“click"替換為 @tap.capture.stop="click"。

Taro 元素的事件處理和 DOM 元素的很相似。但是有一點語法上的不同:

Taro 事件繫結屬性的命名採用駝峰式寫法,而不是小寫。 如果採用 JSX 的語法你需要傳入一個函式作為事件處理函式,而不是一個字串 (DOM 元素的寫法)。 例如,傳統的微信小程式模板:

小程式第三方框架對比 ( wepy / mpvue / taro )

Taro 中稍稍有點不同:

小程式第三方框架對比 ( wepy / mpvue / taro )

在 Taro 中另一個不同是你不能使用 catchEvent 的方式阻止事件冒泡。你必須明確的使用 stopPropagation。例如,阻止事件冒泡你可以這樣寫:

小程式第三方框架對比 ( wepy / mpvue / taro )

request請求

wepy對wx.request做了接受引數的修改,值得一提的是它提供了針對全域性的intercapter攔截器

小程式第三方框架對比 ( wepy / mpvue / taro )

攔截器

小程式第三方框架對比 ( wepy / mpvue / taro )

taro對request進行了二次封裝,可以使用Taro.request(OBJECT)發起網路請求,支援 Promise 化使用。

小程式第三方框架對比 ( wepy / mpvue / taro )

小程式第三方框架對比 ( wepy / mpvue / taro )
小程式第三方框架對比 ( wepy / mpvue / taro )
mpvue沒有對request做特殊優化,與原生相同,可以自己根據需要進行封裝

狀態管理

  • wepy 可引用Redux和Mbox,目前wepy的腳手架內已經整合了redux,選擇需要即可;
  • mpVue使用vuex;
  • taro使用Redux;

如何選擇適合自己的專案

  • 如果只需要做一個微信小程式則根據自己的擅長框架選擇mpvue或taro
  • 如果是當前老專案想像向程式遷移同時老專案又是使用vue開發,建議使用mpvue或wepy
  • 如果是老專案使用react開發且需要部分遷移小程式,建議使用taro
  • 如果是新專案且新專案需要同時支援微信小程式和支付寶小程式, 建議使用原生開發,因為目前框架的轉譯支付寶小程式支援並不是很好,且出了問題不好定位修改, 但如果是小demo不涉及太多邏輯的專案都可以使用框架作為嚐鮮; 但如果是涉及太多互動邏輯的則不建議使用框架轉譯,由於支付寶小程式在檢視層基本與小程式一致所以建議手動更改替換部分方法和全域性替換一些屬性或檔名,如wxml替換為axml這種, 手動轉換時間比大概是四比一; 當然如果人手足夠一端開發一個是最好的...

時刻前端新鮮技術推送,定期前端精品文章分享,歡迎關注公眾號前端小苑。

小程式第三方框架對比 ( wepy / mpvue / taro )

相關文章