MINA
是在微信中開發小程序的框架。其目標是經過儘量簡單、高效的方式讓開發者能夠在微信中開發具備原生 APP
體驗的服務。html
MINA
提供了本身的視圖層描述語言 WXML
和 WXSS
,以及基於 JavaScript
的邏輯層框架,核心是一個響應的數據綁定系統。整個系統分爲視圖層(View
)和邏輯層(App Service
),並在視圖層與邏輯層間提供了數據傳輸和事件系統,可讓開發者能夠方便的聚焦於數據與邏輯上。web
MINA
讓數據與視圖保持同步很是簡單。當作數據修改的時候,只須要在邏輯層修改數據,視圖層就會作相應的更新。MINA
是騰訊給微信小程序命名的框架,實際上應用的是目前業界最著名的 MVVM
模式。算法
咱們都知道小程序提供了不少方便快捷的自定義組件(標籤),但你知道小程序的這些組件編譯事後會渲染成什麼嗎?先說答案,其實 wxml
通過編譯後會渲染成 html
。很簡單的一點,你發如今小程序內編寫 html
標籤,最終也能夠運行。小程序
光說可能體會不到,下面開始探尋小程序真實渲染的樣子。先看下開發者工具內 wxml
的內容,待會和真實渲染的內容作對比。微信小程序
接下來一步步找到小程序 wxml
渲染完成的真實樣子,工具菜單欄點擊微信開發者工具,選擇調試微信開發者工具。打開的控制檯能夠調試整個微信開發者工具,用調試箭頭指向小程序內容區域,這時能夠看到小程序視圖層是被嵌套在 webview
的 iframe
內。微信
可是當咱們點開 iframe
是沒法查看到裏面內容的。若是想要查看調試 webview
,只需選中 webview
打開它的調試工具便可,在控制檯輸入如下代碼:微信開發
$$('webview')[0].showDevTools(true)
能夠看到又打開了一個調試窗口,這裏面就是小程序視圖層渲染的真實樣子:框架
能夠看到結構和 wxml
裏的內容幾乎如出一轍,只是 topbar
變成了 wx-topbar
,view
變成了 wx-view
等。這些都是內部實現的一套對應小程序標籤的 webComponent
組件,而 webComponent
實際渲染出來仍是 html
標籤。dom
轉換過程是微信開發者工具內部經過一個可執行編譯工具實現對小程序文件轉換。在微信開發者工具控制檯輸入 openVendor()
會打開一個文件夾,裏面存放着微信的基礎庫及工具,在裏面能夠找到 wcc.exe
、wcsc.exe
執行文件,分別對應 wxml
和 wxss
的文件轉換。xss
該工具能夠單獨對小程序文件進行轉換,使用方法 ./wcc -d wxml文件路徑 >> 輸出路徑
。例如,將工具複製到一個文件夾內,再將一個 wxml
放入該文件夾內,命令行輸入 :
./wcc -d index.wxml >> index.js
可能有人很好奇爲何是生成 js
文件,而不是 html
文件。緣由很簡單,由於須要處理 wxml
的動態綁定數據。看看這個 js
文件生成的是什麼:
由於這些都是混淆壓縮過的代碼,基本沒有可讀性。這裏只須要注意一個函數就好,那就是 $gwx
。這是個很關鍵的函數,它的做用是生成虛擬dom樹,用於渲染真實節點。
接下來回到 webview
調試窗口,在 head
內找到這段插入的 script
標籤代碼:
有沒有很熟悉,沒錯,就是和上面轉換後的代碼是同一個東西。也就是說,咱們的 wxml
文件經過編譯,最終在視圖層中執行的就是這段 js
代碼(這裏只是能夠大概這麼理解,實際須要向邏輯層獲取數據才能渲染頁面)。控制檯輸入 $gwx
發現這個函數存在,那麼這個函數如何生成虛擬dom呢?$gwx
函數的第一個參數接收一個路徑參數,這個路徑就是 wxml
文件路徑,此時在控制檯輸入:
let generateFunc = $gwx('./pages/index/index.wxml')
generateFunc()
這時頁面虛擬dom就生成出來了:
單純調用 generateFunc
生成出來的虛擬dom是沒有動態綁定數據的,若是想要動態的綁定數據,在調用 generateFunc
時傳入一個數據對象。可是數據全在邏輯層裏,這時就須要進行通訊了。
首先要知道小程序時運行在基礎庫之上的,但它們都是壓縮打包好的,後面找到反編譯出來的基礎庫代碼,其中最重要的就是 WAService.js
和 WAWebview.js
,它們分別是視圖層和邏輯層的核心實現。
它們之間須要一個橋樑來進行通訊,那就是 JS Bridge
。JS Bridge
提供調用原生功能的接口(攝像頭,定位等),它的核心是構建原生和非原生間消息通訊的通道,並且這個通訊的通道是雙向的。經過 JS Bridge
的發佈訂閱方法,視圖層和邏輯層進行數據通訊。
接下來看看視圖層和邏輯層的交互流程:
wxml
轉換成對應的
js
文件,等待生成虛擬dom函數
$gwx
準備完成,使用
dispatchEvent
通知
WAWebview
。
WAWebview
監聽到
generateFuncReady
事件觸發,使用
WeixinJSBridge.publish
向邏輯層通訊。
邏輯層處理邏輯,也就是咱們日常寫的小程序 js
文件裏的東西,而後經過 JS Bridge
通知並返回數據給視圖層。
視圖層接收到數據,將數據傳入生成虛擬dom的函數內,渲染頁面,固然小程序也有相應的diff算法。
例如在 wxml
中綁定一個動態數據 title
,視圖層接收到數據後,從新生成虛擬dom
generateFunc({
title: '標題'
})
JS Bridge
通知到視圖層,視圖層再次調用生成虛擬dom的函數,更新頁面。
wxss
工做原理和 wxml
差很少,都是經過工具轉換爲 js
。爲何又是轉換成 js
,由於有 rpx
單位,須要根據手機尺寸進行設置 px
。
wcsc.exe
轉換命令以下:
./wcsc -js index.wxss >> index.js
能夠看到文件開頭就是對 rpx
的轉換
以後建立 style
標籤,動態添加到視圖層中
附上 WAService.js 和 WAWebview.js 的代碼做爲學習參考。