今天,我們來介紹一款由美團點評研發(fā),使用 Vue.js 來開發(fā)微信小程序的前端框架 —— mpVue。使用此框架,開發(fā)者將得到完整的 Vue.js 開發(fā)體驗,同時為 H5 和小程序提供了代碼復用的能力。如果想將 H5 項目改造為小 ...
在尤大微博鋪墊著“將會引入一些關(guān)于 TypeScript 的改進”一周之后,代號為 Level E 的 Vue.js 2.5 帶著日漫風來到了我們眼前。從 Release Notes 可以看到,Vue.js 2.5 有著更好的 TypeScript 集成,更好的錯誤處理,更好地支持單文件組件中的函數(shù)式組件以及與環(huán)境無關(guān)的服務(wù)端渲染。具體如下:
更好的 TypeScript 集成
得益于 TypeScript 團隊的幫助,2.5 提供了大大改進的類型聲明:
注意:TypeScript 用戶還應將以下包更新為最新版本從而兼容類型聲明:vue-router,vuex,vuex-router-sync 和 vue-class-component。
更好地錯誤處理
在 2.4 及更早版本中,我們通常使用全局 config.errorHandleroption 來處理應用程序中的意外錯誤。 我們還有 renderError 組件選項來處理渲染函數(shù)中的錯誤。 但是,我們?nèi)鄙偬幚響贸绦蛱囟ú糠謨?nèi)的泛型錯誤的機制。
在2.5中,我們引入了新的 errorCaptured 鉤子。 具有此鉤子的組件捕獲其子組件樹(不包括其自身)中的所有錯誤(不包括在異步回調(diào)中調(diào)用的那些)。 如果你熟悉 React,這與 React 16 中引入的錯誤邊界的概念相似。鉤子接收與全局 errorHandler 相同的參數(shù),你可以利用這個 鉤子(https:// gist.github.com/yyx990803/ 9bdff05e5468a60ced06c29c39114c6b #error-handling-with-errorcaptured-hook)來優(yōu)雅地處理和顯示錯誤。
更好地支持 SFC 中的函數(shù)式組件
使用 vue-loader> = 13.3.0 和 Vue 2.5,在 * .vue 文件中定義為單個文件組件的函數(shù)式組件現(xiàn)在可以得到正確的模板編譯,Scoped CSS和熱重新加載支持。 這使得將葉子組件轉(zhuǎn)換為函數(shù)式的更為容易,從而進行性能優(yōu)化。
與環(huán)境無關(guān)的服務(wù)端渲染
vue-server-renderer 的默認構(gòu)建假定一個 Node.js 環(huán)境,這使得它在有的 JavaScript 運行時(如 php-v8js 或Nashorn)中不可用。 在 2.5 中,我們已經(jīng)發(fā)布了一個與環(huán)境無關(guān)的 vue-server-renderer 版本,可以在瀏覽器或純 JavaScript 引擎中使用。 這可以打開有趣的策略,例如直接在 PHP 進程中使用 Vue 服務(wù)端渲染。
同樣,建議你查看完整的發(fā)布說明從而了解其他 API 的改進,包括 v-on,v-model,scoped slot,provide/inject 等。
Vue 2.5.0 源碼下載:https://codeload.github.com/vuejs/vue/zip/v2.5.0
Vue.js 這款漸進式的 JavaScript 框架自 2013 年發(fā)布至今,其簡潔的語法設(shè)計、輕量快速的特點深受技術(shù)社區(qū)喜愛,在國內(nèi)外都獲得了非常廣泛的應用及拓展,比如餓了么的開源組件庫 Element UI 即是 Vue 開發(fā),而阿里巴巴的 Weex 與 Vue 也多有合作。
今天,我們來介紹一款由美團點評研發(fā),使用 Vue.js 來開發(fā)微信小程序的前端框架 —— mpVue。使用此框架,開發(fā)者將得到完整的 Vue.js 開發(fā)體驗,同時為 H5 和小程序提供了代碼復用的能力。如果想將 H5 項目改造為小程序,或開發(fā)小程序后希望將其轉(zhuǎn)換為 H5,mpVue將是十分契合的方案。
為了提高開發(fā)效率,增強開發(fā)體驗,我們造了個用 Vue 開發(fā)小程序的輪子
小程序開發(fā)特點
微信小程序推薦簡潔的開發(fā)方式,通過多頁面聚合完成輕量的產(chǎn)品功能。小程序以離線包方式下載到本地,通過微信客戶端載入和啟動,開發(fā)規(guī)范簡潔,技術(shù)封裝徹底,自成開發(fā)體系,有 Native 和 H5 的影子,但又絕不雷同。
小程序本身定位為一個簡單的邏輯視圖層框架,官方并不推薦用來開發(fā)復雜應用,但業(yè)務(wù)需求卻難以做到精簡。復雜的應用對開發(fā)方式有較高的要求,如組件和模塊化、自動構(gòu)建和集成、代碼復用和開發(fā)效率等,但小程序開發(fā)規(guī)范較大地限制了這部分能力。為了解決上述問題,提供更好的開發(fā)體驗,我們創(chuàng)造了 mpVue,通過使用 Vue.js 開發(fā)微信小程序。
mpVue 是什么
mpVue 是一套定位于開發(fā)小程序的前端開發(fā)框架,其核心目標是提高開發(fā)效率,增強開發(fā)體驗。使用該框架,開發(fā)者無須了解小程序開發(fā)規(guī)范,只需要熟悉 Vue.js 基本語法即可上手。框架提供了完全的 Vue.js 開發(fā)體驗,開發(fā)者編寫 Vue.js 代碼,mpVue 將其解析轉(zhuǎn)換為小程序并確保其正確運行。此外,框架還通過 CLI 工具向開發(fā)者提供 Quick Start 示例代碼,開發(fā)者只需執(zhí)行一條簡單命令,即可獲得可運行的項目。
為什么做 mpVue
在小程序內(nèi)測之初,我們計劃快速迭代出一款對標 H5 的產(chǎn)品實現(xiàn),其核心訴求在于快速實現(xiàn)、代碼復用、低成本和高效率等。隨后我們經(jīng)歷了多個小程序建設(shè),結(jié)合業(yè)務(wù)場景、技術(shù)選型和小程序開發(fā)方式,整理匯總出了開發(fā)階段面臨的主要問題:
具體體現(xiàn)為:
另一方面,小程序開發(fā)方式與 H5 近似,因此我們考慮和 H5 做代碼復用。同時,沿襲團隊技術(shù)棧選型,我們將 Vue.js 確定為小程序開發(fā)規(guī)范。使用 Vue.js 開發(fā)小程序,將直接帶來如下開發(fā)效率的提升:
為什么是 Vue.js?這取決于團隊技術(shù)棧選型,引入新的選型對統(tǒng)一技術(shù)棧和提高開發(fā)效率相悖,有違開發(fā)工具服務(wù)業(yè)務(wù)的初衷。
mpVue 的演進
mpVue 的形成,來源于業(yè)務(wù)場景和需求,最終方案的確定,經(jīng)歷了三個階段。
mpVue 設(shè)計思路
Vue.js 和小程序都是典型的邏輯視圖層框架,邏輯層和視圖層之間的工作方式為:數(shù)據(jù)變更驅(qū)動視圖更新;視圖交互觸發(fā)事件,事件響應函數(shù)修改數(shù)據(jù)再次觸發(fā)視圖更新,如圖 1 所示。
圖 1 小程序?qū)崿F(xiàn)原理
鑒于 Vue.js 和小程序一致的工作原理,我們思考將小程序的功能托管給 Vue.js,在正確的時機將數(shù)據(jù)變更同步到小程序,從而達到開發(fā)小程序的目的。這樣,我們可以將精力聚焦在 Vue.js 上,參照 Vue.js 編寫與之對應的小程序代碼,小程序負責視圖層展示,所有業(yè)務(wù)和邏輯收斂到 Vue.js 中,Vue.js 數(shù)據(jù)變更后同步到小程序,如圖 2 所示。如此一來,我們就獲得了以 Vue.js 的方式開發(fā)小程序的能力。為此,我們設(shè)計的方案如下:
圖 2 mpVue 實現(xiàn)原理
Vue 代碼:
小程序代碼:
并在此基礎(chǔ)上,附加如下機制:
這套機制總結(jié)起來非常簡單,但實現(xiàn)卻相當復雜。在揭秘具體實現(xiàn)之前,讀者可能會有這樣一些疑問:
上述問題包含了 mpVue 框架的核心內(nèi)容,下文將仔細為你道來。首先,mpVue 為提高效率而生,本身提供了自動生成小程序代碼的能力,小程序代碼根據(jù) Vue.js 代碼構(gòu)建得到,并不需要同時開發(fā)兩套代碼。
Vue.js 視圖層渲染由 Render 方法完成,同時在內(nèi)存中維護著一份虛擬 DOM,mpVue 無需使用 Vue.js 完成視圖層渲染,因此我們改造了 Render 方法,禁止視圖層渲染。熟悉源代碼的讀者都知道 Vue RunTime 有多個平臺的實現(xiàn),除了我們常見的 Web 平臺,還有 Weex。從現(xiàn)在開始,我們增加了新的平臺 mpVue。
再看第三個問題,生命周期和數(shù)據(jù)同步是 mpVue 框架的靈魂,Vue.js 和小程序的數(shù)據(jù)彼此隔離,各自有不同的更新機制。mpVue 從生命周期和事件回調(diào)函數(shù)切入,在 Vue.js 觸發(fā)數(shù)據(jù)更新時實現(xiàn)數(shù)據(jù)同步。小程序通過視圖層呈現(xiàn)給用戶、通過事件響應用戶交互,Vue.js 在后臺維護著數(shù)據(jù)變更和邏輯。可以看到,數(shù)據(jù)更新發(fā)端于小程序,處理自 Vue.js,Vue.js 數(shù)據(jù)變更后再同步到小程序。為實現(xiàn)數(shù)據(jù)同步,mpVue 修改了 Vue.js RunTime 實現(xiàn),在 Vue.js 的生命周期中增加了更新小程序數(shù)據(jù)的邏輯。
而用戶交互觸發(fā)的數(shù)據(jù)更新則是通過事件代理機制完成。在 Vue.js 代碼中,事件響應函數(shù)對應到組件的 method 方法,Vue.js 自動維護了上下文環(huán)境。然而在小程序中并沒有類似的機制,又因為 Vue.js 執(zhí)行環(huán)境中維護著一份實時的虛擬 DOM,這與小程序的視圖層完全對應。我們思考,在小程序組件節(jié)點上觸發(fā)事件后,只要找到虛擬 DOM 上對應的節(jié)點,觸發(fā)對應的事件不就完成了么。Vue.js 事件響應如果觸發(fā)了數(shù)據(jù)更新,其生命周期函數(shù)更新將自動觸發(fā),在此函數(shù)上同步更新小程序數(shù)據(jù),數(shù)據(jù)同步就實現(xiàn)了。
mpVue 如何使用
mpVue 框架本身由多個 npm 模塊構(gòu)成,入口模塊已經(jīng)處理好依賴關(guān)系,開發(fā)者只需要執(zhí)行如下代碼即可完成本地項目創(chuàng)建。
# 安裝 vue-cli
$ npm install --global vue-cli
# 根據(jù)模板項目創(chuàng)建本地項目,目前為內(nèi)網(wǎng)地址,暫穩(wěn)開放
$ vue init ‘bitbucket:xxx.meituan.com:hfe/mpvue-quickstart’ --clone my-project
# 安裝依賴和啟動自動構(gòu)建
$ cd my-project
$ npm install
$ npm run dev
執(zhí)行完上述命令,在當前項目的 dist 子目錄將構(gòu)建出小程序目標代碼,使用小程序開發(fā)者工具載入 dist 目錄即可啟動本地調(diào)試和預覽。
示例項目遵循 Vue.js 模板項目規(guī)范,通過 Vue.js 命令行工具 vue-cli 創(chuàng)建。代碼組織形式與 Vue.js 官方實例保持一致,我們?yōu)樾〕绦蚨ㄖ屏?Vue.js RunTime 和 Webpack 加載器,此部分依賴也已經(jīng)內(nèi)置到項目中。
針對小程序開發(fā)中常見的兩類代碼復用場景,mpVue 框架為開發(fā)者提供了解決思路和技術(shù)支持,開發(fā)者只需要在此指導下進行項目配置和改造。
將小程序轉(zhuǎn)換為 H5
直接使用 Vue.js 規(guī)范開發(fā)小程序,代碼本身與 H5 并無不同,具體代碼差異會集中在平臺 API 部分。此外無需明顯改動,改造主要分以下幾個部分:
將 H5 轉(zhuǎn)換為小程序
已經(jīng)使用 Vue.js 開發(fā)完 H5,則需要完成以下事宜:
根據(jù)小程序開發(fā)平臺提供的能力,我們最大程度地支持了 Vue.js 語法特性,但部分功能現(xiàn)階段暫時尚未實現(xiàn),具體見表 1。
表 1 mpVue 暫不支持的語法特性
mpVue 框架的目標是將小程序和 H5 的開發(fā)方式通過 Vue.js 建立關(guān)聯(lián),達到最大程度的代碼復用。但由于平臺差異的客觀存在(主要集中在實現(xiàn)機制、底層 API 能力差異),我們無法做到代碼 100%復用,平臺差異部分的改造成本無法避免。對于代碼復用的場景,開發(fā)者需要重點思考如下問題并做好準備:
mpVue 最佳實踐
在表 2 中,我們對微信小程序、mpVue、WePY 這三個開發(fā)框架的主要能力和特點做了橫向?qū)Ρ龋瑤椭蠹伊私獠煌蚣艿膫?cè)重點,結(jié)合業(yè)務(wù)場景和開發(fā)習慣,確定技術(shù)方案。對于如何更好地使用 mpVue 進行小程序開發(fā),我們總結(jié)了一些最佳實踐。
表 2 框架主要能力及特性對比
結(jié)語
mpVue 框架已經(jīng)在業(yè)務(wù)項目中得到實踐和驗證,目前開發(fā)文檔也已經(jīng)就緒,正在做開源前的最后準備,希望能夠為小程序和 Vue.js 生態(tài)貢獻一份力量。mpVue 的初衷是希望讓 Vue.js 的開發(fā)者以低成本接入小程序開發(fā),其能力和使用體驗還有待進一步的檢驗。我們未來會繼續(xù)擴展現(xiàn)有功能、解決用戶的問題和需求、優(yōu)化開發(fā)體驗、完善周邊生態(tài)建設(shè),以幫助到更多的開發(fā)者。
需要說明一下,mpVue 是通過 fork Vue.js 源碼進行二次開發(fā),新增加了 mp 平臺的 Vue.js 實現(xiàn),我們保留了跟隨 Vue.js 版本升級的能力,希望未來能夠?qū)崿F(xiàn)更好的能力增強,最后感謝 Vue.js 框架和微信小程序?qū)I(yè)界帶來的便利