小程序可以调用宿主环境提供的微信客户端的能力
1 渲染层和逻辑层
WXML 模板和 WXSS 样式工作在渲染层,JS 脚本工作在逻辑层
1.1 通信模型
-
小程序的渲染层和逻辑层分别由
2个线程
管理-
渲染层的界面使用了
WebView
进行渲染 -
逻辑层采用
JsCore
线程运行 JS 脚本
-
-
一个小程序存在多个界面,所以渲染层存在多个
WebView
线程 -
这两个线程的通信会经由微信客户端做中转,逻辑层发送网络请求也经由
Native
转发
1.2 数据驱动
- WXML 可以先转成 JS 对象,然后再渲染出真正的
DOM树
1.3 双线程下的界面渲染
小程序的逻辑层和渲染层是分开的两个线程
-
在渲染层,宿主环境会把
WXML
转化成对应的JS对象
-
在逻辑层发生数据变更的时候,我们需要通过宿主环境提供的
setData()
方法把数据从逻辑层传递到渲染层 -
再经过对比前后差异,把差异应用在原来的
Dom树
上,渲染出正确的UI界面
2 程序与页面
2.1 程序
“小程序”指产品层面的程序,“程序”指代码层面的程序实例
程序构造器 App()
宿主环境提供了
App()
构造器用来注册一个 程序App,需要留意的是App()
构造器必须写在项目根目录的 app.js 里,App 实例是单例对象,在其他 JS 脚本中可以使用宿主环境提供的getApp()
来获取程序实例
小程序全局数据
- App 实例是单例的,因此不同页面直接可以通过 App 实例下的属性来共享数据
注意:所有页面的脚本逻辑都是跑在同一个
JsCode
线程,页面使用定时器,然后跳转到其它页面时,这些定时器并没有被清除,需要开发者自己在页面离开时清理
2.2 页面
页面构造器 Page()
宿主环境提供了
Page()
构造器用来注册一个小程序页面,Page() 在页面脚本 page.js 中调用
- Page 构造器接受一个 Object 参数,其中
data
属性是当前页面 WXML 模板中可以用来做数据绑定的初始数据
页面的数据
通过在 Page 实例下的方法调用
this.setData()
把数据传递给渲染层,从而达到更新界面的目的
-
由于小程序的渲染层和逻辑层分别在两个线程中运行,所以
setData
传递数据实际是一个 异步 的过程,所以setData
的第二个参数是一个callback
回调,在这次setData
对界面渲染完毕后触发 -
data 中的
key
可以非常灵活,以数据路径的形式给出-
this.setData({"d[0]": 100})
-
this.setData({"d[1].text": 'Goodbye'})
-
保持一个原则就可以提高小程序的渲染性能:每次只设置需要改变的最小单位数据。
-
直接修改 Page 实例的
this.data
而不调用this.setData
是无法改变页面的状态的,还会造成数据不一致
页面的用户行为
小程序宿主环境提供了四个和页面相关的用户行为回调
-
下拉刷新
onPullDownRefresh
-
在 app.json 的 window 选项| page.json 中设置
enablePullDownRefresh
为true
-
当处理完数据刷新后,
wx.stopPullDownRefresh
可以停止当前页面的下拉刷新
-
-
上拉触底
onReachBottom
-
在 app.json 的 window 选项| page.json 中设置触发距离
onReachBottomDistance
-
在触发距离内滑动期间,本事件只会触发一次
-
-
页面滚动
onPageScroll
-
用户转发
onShareAppMessage
页面跳转和路由
小程序宿主环境限制了这个页面栈的最大层级为10层
3 组件
组件就是小程序页面的基本组成单元
- 所有组件名和属性都是小写,多个单词会以英文横杠 "-" 进行连接
4 API
wx 对象实际上就是小程序的宿主环境所提供的全局对象,几乎所有小程序的 API 都挂载在 wx 对象底下(除了 Page/App 等特殊的构造器)
5 事件
5.1 什么是事件
把“用户在渲染层的行为反馈”以及“组件的部分状态反馈”抽象为渲染层传递给逻辑层的“事件”
5.2 事件类型和事件对象
常见事件类型
类型 | 触发条件 |
---|---|
touchstart |
手指触摸动作开始 |
touchmove |
手指触摸后移动 |
touchcancel |
手指触摸动作被打断,如来电提醒,弹窗 |
touchend |
手指触摸动作结束 |
tap |
手指触摸后马上离开 |
longpress |
手指触摸后,超过350ms再离开,如果指定了事件回调函数并触发了这个事件,tap事件将不被触发 |
longtap |
手指触摸后,超过350ms再离开(推荐使用longpress事件代替) |
-
当事件回调触发的时候,会收到一个事件对象,需要注意
target
和currentTarget
属性的区别currentTarget
为当前事件所绑定的组件target
为触发该事件的源头组件
5.3 事件绑定与冒泡捕获
以
key="value"
的形式
-
key
以bind
或者catch
开头,然后跟上事件的类型 -
value
是一个字符串,需要在对应的页面 Page 构造器中定义同名的函数,否则触发事件时在控制台会有报错信息
-
bind
和capture-bind
的含义分别代表事件的冒泡阶段和捕获阶段 -
bind
事件绑定不会阻止冒泡事件向上冒泡,catch
事件绑定可以阻止冒泡事件向上冒泡
其他组件自定义事件,如无特殊声明都是非冒泡事件
如
<form/>
的submit事件,<input/>
的input事件,<scroll-view/>
的scroll事件