眾所周知如今市面上端的形態(tài)多種多樣,手機Web、ReactNative、微信小程序, 支付寶小程序, 快應用等,每一端都是巨大的流量入口,當業(yè)務要求同時在不同的端都要求有所表現(xiàn)的時候,針對不同的端去編寫多套代碼的成本顯然非常高,這時候只編寫一套代碼就能夠適配到多端的能力就顯得極為需要。但面對目前市面上成熟的小程序第三方框架如何針對自己的需求進行選擇也是一個麻煩事,本文針對當前市面上的三大轉譯框架進行一個綜合對比,希望能對大家的技術選擇有所幫助,如有哪里不妥的地方希望指正; 小程序開發(fā)有哪些痛點?
為什么使用第三方框架?
第三方框架對比 wepy mpvue taro在這里我通過對目前已開源的三種常用小程序框架做一個綜合對比, 還有一個叫nanchi的基于react的小程序轉譯框架,由于沒來的及研究暫不做比較;
騰訊團隊開源的一款類vue語法規(guī)范的小程序框架,借鑒了Vue的語法風格和功能特性,支持了Vue的諸多特征,比如父子組件、組件之間的通信、computed屬性計算、wathcer監(jiān)聽器、props傳值、slot槽分發(fā),還有很多高級的特征支持:Mixin混合、攔截器等;WePY發(fā)布的第一個版本是2016年12月份,也就是小程序剛剛推出的時候,到目前為止,WePY已經(jīng)發(fā)布了52個版本, 最新版本為1.7.2;
美團團隊開源的一款使用 Vue.js 開發(fā)微信小程序的前端框架。使用此框架,開發(fā)者將得到完整的 Vue.js 開發(fā)體驗,同時為 H5 和小程序提供了代碼復用的能力。mpvue在發(fā)布后的幾天間獲得2.7k的star,上升速度飛起,截至目前為止已經(jīng)有13.7k的star;
京東凹凸實驗室開源的一款使用 React.js 開發(fā)微信小程序的前端框架。它采用與 React 一致的組件化思想,組件生命周期與 React 保持一致,同時支持使用 JSX 語法,讓代碼具有更豐富的表現(xiàn)力,使用 Taro 進行開發(fā)可以獲得和 React 一致的開發(fā)體驗。,同時因為使用了react的原因所以除了能編譯h5, 小程序外還可以編譯為ReactNative; Star
生命周期同為vue規(guī)范的mpvue和wepy的生命周期和各種方法不盡相同 wepywepy生命周期基本與原生小程序相同,再此基礎上糅合了一些vue的特性; 對于WePY中的methods屬性,因為與Vue中的使用習慣不一致,非常容易造成誤解,這里需要特別強調一下:WePY中的methods屬性只能聲明頁面wxml標簽的bind、catch事件,不能聲明自定義方法,這與Vue中的用法是不一致的?! ?/p> import wepy from 'wepy'; export default class MyPage extends wepy.page { // export default class MyComponent extends wepy.component { customData = {} // 自定義數(shù)據(jù) customFunction () {} //自定義方法 onLoad () {} // 在Page和Component共用的生命周期函數(shù) onShow () {} // 只在Page中存在的頁面生命周期函數(shù) config = {}; // 只在Page實例中存在的配置數(shù)據(jù),對應于原生的page.json文件 data = {}; // 頁面所需數(shù)據(jù)均需在這里聲明,可用于模板數(shù)據(jù)綁定 components = {}; // 聲明頁面中所引用的組件,或聲明組件中所引用的子組件 mixins = []; // 聲明頁面所引用的Mixin實例 computed = {}; // 聲明計算屬性(詳見后文介紹) watch = {}; // 聲明數(shù)據(jù)watcher(詳見后文介紹) methods = {}; // 聲明頁面wxml中標簽的事件處理函數(shù)。注意,此處只用于聲明頁面wxml中標簽的bind、catch事件,自定義方法需以自定義方法的方式聲明 events = {}; // 聲明組件之間的事件處理函數(shù) } mpvue mpvue 除了 Vue 本身的生命周期外,還兼容了小程序生命周期,這部分生命周期鉤子的來源于微信小程序的 Page, 除特殊情況外,不建議使用小程序的生命周期 鉤子。 1Vue 3 beforeCreate 4 created 5 beforeMount 6 mounted 7 beforeUpdate 8 updated 9 activated 10 deactivated 11 beforeDestroy 12 destroyed 簡單示例 new Vue({ data: { a: 1 }, created () { // `this` 指向 vm 實例 console.log('a is: ' + this.a) }, onShow () { // `this` 指向 vm 實例 console.log('a is: ' + this.a, '小程序觸發(fā)的 onshow') } }) // => "a is: 1" taro與react生命周期完全相同class Clock extends Component { constructor (props) { super(props) this.state = { date: new Date() } } componentDidMount() { } componentWillUnmount() { } render () { return ( <View> <Text>Hello, world!</Text> <Text>現(xiàn)在的時間是 {this.state.date.toLocaleTimeString()}.</Text> </View> ) } } 列表渲染在列表渲染上三者也分別有不同的應用方法wepy當需要循環(huán)渲染W(wǎng)ePY組件時(類似于通過 <template> <!-- 注意,使用for屬性,而不是使用wx:for屬性 --> <repeat for="{{list}}" key="index" index="index" item="item"> <!-- 插入<script>腳本部分所聲明的child組件,同時傳入item --> <child :item="item"></child> </repeat> </template> <script> import wepy from 'wepy'; // 引入child組件文件 import Child from '../components/child'; export default class Index extends wepy.component { components = { // 聲明頁面中要使用到的Child組件的ID為child child: Child } data = { list: [{id: 1, title: 'title1'}, {id: 2, title: 'title2'}] } } </script> mpvue使用v-for與vue一致,只是需要注意一點,嵌套列表渲染,必須指定不同的索引! <!-- 在這種嵌套循環(huán)的時候, index 和 itemIndex 這種索引是必須指定,且別名不能相同,正確的寫法如下 --> <template> <ul v-for="(card, index) in list"> <li v-for="(item, itemIndex) in card"> {{item.value}} </li> </ul> </template> taro的列表循環(huán)用法基本與react相同,有一點需要注意,在 React 中,JSX 是會編譯成普通的 JS 的執(zhí)行,每一個 JSX 元素,其實會通過 const list = this.state.list.map(l => { if (l.selected) { return <li>{l.text}</li> } }).filter(React.isValidElement) 但是 Taro 中,JSX 會編譯成微信小程序模板字符串,因此你不能把 const list = this.state.list .filter(l => l.selected) .map(l => { return <li>{l.text}</li> }) 事件處理mpvue目前全支持小程序的事件處理器,引入了 Vue.js 的虛擬 DOM ,在前文模版中綁定的事件會被掛在到 vnode 上,同時 compiler 在 wxml 上綁定了小程序的事件,并做了相應的映射,所以你在真實點擊的時候通過 runtime 中 // 事件映射表,左側為 WEB 事件,右側為 小程序 對應事件 { 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' } 踩坑注意(官方文檔):
wepy事件綁定區(qū)別于vue,根據(jù)原生小程序事件提供了語法優(yōu)化 綁定事件 捕獲監(jiān)聽事件 Taro 元素的事件處理和 DOM 元素的很相似。但是有一點語法上的不同: Taro 事件綁定屬性的命名采用駝峰式寫法,而不是小寫。 如果采用 JSX 的語法你需要傳入一個函數(shù)作為事件處理函數(shù),而不是一個字符串 (DOM 元素的寫法)。 例如,傳統(tǒng)的微信小程序模板: <button onclick="activateLasers">
Activate Lasers
</button>
Taro 中稍稍有點不同: <button onClick={this.activateLasers}> Activate Lasers </button> 在 Taro 中另一個不同是你不能使用 class Toggle extends React.Component { constructor (props) { super(props) this.state = {isToggleOn: true} } onClick = (e) => { e.stopPropagation() this.setState(prevState => ({ isToggleOn: !prevState.isToggleOn })) } render () { return ( <button onClick={this.onClick}> {this.state.isToggleOn ? 'ON' : 'OFF'} </button> ) } } request請求wepy對wx.request做了接受參數(shù)的修改,值得一提的是它提供了針對全局的intercapter攔截器
// 原生代碼: wx.request({ url: 'xxx', success: function (data) { console.log(data); } }); // WePY 使用方式, 需要開啟 Promise 支持,參考開發(fā)規(guī)范章節(jié) wepy.request('xxxx').then((d) => console.log(d)); // async/await 的使用方式, 需要開啟 Promise 和 async/await 支持,參考 WIKI async function request () { let d = await wepy.request('xxxxx'); console.log(d); } 攔截器 import wepy from 'wepy'; export default class extends wepy.app { constructor () { // this is not allowed before super() super(); // 攔截request請求 this.intercept('request', { // 發(fā)出請求時的回調函數(shù) config (p) { // 對所有request請求中的OBJECT參數(shù)對象統(tǒng)一附加時間戳屬性 p.timestamp = +new Date(); console.log('config request: ', p); // 必須返回OBJECT參數(shù)對象,否則無法發(fā)送請求到服務端 return p; }, // 請求成功后的回調函數(shù) success (p) { // 可以在這里對收到的響應數(shù)據(jù)對象進行加工處理 console.log('request success: ', p); // 必須返回響應數(shù)據(jù)對象,否則后續(xù)無法對響應數(shù)據(jù)進行處理 return p; }, //請求失敗后的回調函數(shù) fail (p) { console.log('request fail: ', p); // 必須返回響應數(shù)據(jù)對象,否則后續(xù)無法對響應數(shù)據(jù)進行處理 return p; }, // 請求完成時的回調函數(shù)(請求成功或失敗都會被執(zhí)行) complete (p) { console.log('request complete: ', p); } }); } } taro對request進行了二次封裝,可以使用Taro.request(OBJECT)發(fā)起網(wǎng)絡請求,支持
import Taro from '@tarojs/taro' Taro.request({ url: 'http://localhost:8080/test', data: { foo: 'foo', bar: 10 }, header: { 'content-type': 'application/json' } }) .then(res => console.log(res.data)) mpvue沒有對request做特殊優(yōu)化,與原生相同,可以自己根據(jù)需要進行封裝 狀態(tài)管理wepy 可引用Redux和Mbox,目前wepy的腳手架內(nèi)已經(jīng)集成了redux,選擇需要即可; mpVue使用vuex taro使用Redux 如何選擇適合自己的項目
|
|