在內置組件中,有一些組件較為特殊,它們并不完全在Exparser的渲染體系下,而是由客戶端原生參與組件的渲染,這類組件我們稱為“原生組件”,這也是小程序Hybrid技術的一個應用。
[TOC]
### 5.3.1 原生組件運行機制
代碼清單6-8 展示一個地圖組件
~~~
<map latitude="39.92" longtitude="116.46"></map>
~~~
在原生組件內部,其節點樹非常簡單,基本上可以認為只有一個div元素。上面這行代碼在渲染層開始運行時,會經歷以下幾個步聚:
* 組件被創建,包括組件屬性會依次賦值。
* 組件被插入到DOM樹里,瀏覽器內核會立即計算布局,此時我們可以讀取出組件相對頁面的位置(x, y坐標)、寬高。
* 組件通知客戶端,客戶端在相同的位置上,根據寬高插入一塊原生區域,之后客戶端就在這塊區域渲染界面
* 當位置或寬高發生變化時,組件會通知客戶端做相應的調整
我們可以看出,原生組件在WebView這一層的渲染任務是很簡單,只需要渲染一個占位元素,之后客戶端在這塊占位元素之上疊了一層原生界面。因此,原生組件的層級會比所有在WebView層渲染的普通組件要高。
:-: 
:-: 圖6-1 原生組件層級示意圖
引入原生組件主要有3個好處:
1. 擴展Web的能力。比如像輸入框組件(input, textarea)有更好地控制鍵盤的能力。
2. 體驗更好,同時也減輕WebView的渲染工作。比如像地圖組件(map)這類較復雜的組件,其渲染工作不占用WebView線程,而交給更高效的客戶端原生處理。
3. 繞過setData、數據通信和重渲染流程,使渲染性能更好。比如像畫布組件(canvas)可直接用一套豐富的繪圖接口進行繪制。
:-: 表6-1 常用的幾個原生組件
| 組件名 | 名稱 | 是否有 "context" | 描述 |
| --- | --- | --- | --- |
| video | 視頻 | 是 | 播放視頻 |
| map | 地圖 | 是 | 展示地圖 |
| canvas | 畫布 | 是 | 提供一個可以自由繪圖的區域 |
| picker | 彈出式選擇器 | 否 | 初始時沒有界面,點擊時彈出選擇器 |
交互比較復雜的原生組件都會提供“context”,用于直接操作組件。
以canvas為例,小程序提供了`wx.createCanvasContext`方法來創建canvas的context。這是一個可以用于操作canvas的對象,對象下提供了很多繪圖的方法,如“setFillStyle”方法可以設置填充樣式,“fillRect”方法用于繪制矩形(這些方法與HTML DOM Canvas兼容)。
代碼清單6-9 canvas組件context對象示例(WXML代碼)
~~~
<canvas canvas-id="myCanvas"></canvas>
~~~
代碼清單6-10 canvas組件context對象示例(JS代碼)
~~~
const ctx = wx.createCanvasContext('myCanvas')
ctx.setFillStyle('red')
ctx.fillRect(10, 10, 150, 75)
ctx.draw()
~~~
這段代碼可以創建WXML中對應canvas節點的context,通過調用context中的方法,在畫布上繪制一個矩形。
類似于canvas,video、map等原生組件都可以創建context,context中提供的方法非常豐富,可參考有關的文檔詳細了解。
### 5.3.2 原生組件渲染限制
原生組件脫離在WebView渲染流程外,這帶來了一些限制。最主要的限制是:
**一些CSS樣式無法應用于原生組件**,例如,不能在父級節點使用overflow:hidden來裁剪原生組件的顯示區域;不能使用transformrotate讓原生組件產生旋轉等。
開發者最為常見的問題是,原生組件會浮于頁面其他組件之上(相當于擁有正無窮大的z-index值)使其它組件不能覆蓋在原生組件上展示。想要解決這個問題,可以考慮使用cover-view和cover-image組件。這兩個組件也是原生組件,同樣是脫離WebView的渲染流程外,而原生組件之間的層級就可以按照一定的規則控制。
- 微信
- 小程序
- 1. 代碼組成
- 1.1 JSON配置--'*.json'文件
- 1.2 WXML模板--'*.wxml'文件
- 1.3 WXSS樣式--'*.wxss'文件
- 1.4 JavaScript腳本--'*.js'文件
- 2. 客戶端運行
- 2.1 邏輯層和渲染層
- 2.1.1 邏輯層--App Service
- 2.1.2 渲染層/視圖層--View
- 2.1.3 通信模型
- 2.1.4 數據驅動
- 2.1.5 雙線程下的界面渲染
- 2.2 程序與頁面
- 2.3 組件
- 2.4 API
- 2.5 事件
- 2.6 兼容
- 3. 應用設計
- 3.1 Flex布局
- 3.2 界面常見的交互反饋
- 3.3 發起HTTPS網絡通信--wx.request
- 3.4 微信登錄
- 3.5 本地數據緩存
- 3.6 設備能力
- 4. 小程序的協同工作和發布
- 4.1 協同工作
- 4.2 用戶體驗審視
- 4.3 發布
- 4.4 運營
- 5. 底層框架
- 5.1 雙線程模型
- 5.2 組件系統--Exparser框架
- 5.3 原生組件
- 5.4 小程序與客戶端通信原理
- 6. 運行和性能優化
- 6.1 啟動--代碼加載
- 6.2 頁面準備
- 6.3 數據通信
- 6.4 視圖層渲染
- 6.5 原生組件通信
- 7. 小程序基礎庫的更新迭代
- 8. 微信開發者工具
- 騰訊云支持
- wafer
- Wafer2 快速開發 Demo - PHP
- WXAPI
- api列表