在内置组件中,有一些组件较为特殊,它们并不完全在Exparser的渲染体系下,而是由客户端原生参与组件的渲染,这类组件我们称为“原生组件”,这也是小程序Hybrid技术的一个应用。
[TOC]
### 5.3.1 原生组件运行机制
代码清单6-8 展示一个地图组件
~~~
<map latitude="39.92" longtitude="116.46"></map>
~~~
在原生组件内部,其节点树非常简单,基本上可以认为只有一个div元素。上面这行代码在渲染层开始运行时,会经历以下几个步聚:
* 组件被创建,包括组件属性会依次赋值。
* 组件被插入到DOM树里,浏览器内核会立即计算布局,此时我们可以读取出组件相对页面的位置(x, y坐标)、宽高。
* 组件通知客户端,客户端在相同的位置上,根据宽高插入一块原生区域,之后客户端就在这块区域渲染界面
* 当位置或宽高发生变化时,组件会通知客户端做相应的调整
我们可以看出,原生组件在WebView这一层的渲染任务是很简单,只需要渲染一个占位元素,之后客户端在这块占位元素之上叠了一层原生界面。因此,原生组件的层级会比所有在WebView层渲染的普通组件要高。
:-: ![原生组件层级示意图](https://box.kancloud.cn/7538c6020699b760666c647d84990f74_294x522.png)
:-: 图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列表