setData
这是小程序再逻辑层用于设置页面数据的API
setData
函数用于将数据从逻辑层发送到视图层(异步),同时改变对应的this.data
的值(同步)
1. setData更新的过程
- 逻辑层虚拟 DOM 树的遍历和更新,触发组件生命周期和 observer 等
- 逻辑层把修改后的 data 通过 setData 传到渲染层
- 渲染层会根据渲染机制重新生成 VD(虚拟 DOM)树,并更新到对应的 DOM 树上,引起界面变化
- 小程序的视图层目前使用 WebView 作为渲染载体,而逻辑层是由独立的 JavascriptCore 作为运行环境。
- 渲染层中使用双括号语法(带有数据绑定语法的DSL)来描述页面的结构
<view>{{ message }}</view>
2. 当用户按下按钮的时候发生了什么?
通信过程:
- 渲染层 -> Native(点击事件)。
- Native -> 逻辑层(点击事件)。
- 逻辑层 -> Native(setData)。(原生组件可以绕过setData)
- Native -> 渲染层(setData)。(原生组件在 WebView 这一层只需要渲染一个占位元素,之后客户端在这块占位元素之上叠了一层原生界面。)
优化setData的使用
1.使用数据监听器
当一些数据字段被setData设置时,需要执行一些额外的操作
注意:不要在数据监听器中使用setData设置本身监听的数据字段 => 可能导致死循环
1.1 用做computed:
observers: { ‘属性A,属性b’ () {...} }
Component({
attached: function() {
this.setData({
numberA: 1,
numberB: 2,
})
},
observers: {
'numberA, numberB': function(numberA, numberB) {
// 在 numberA 或者 numberB 被设置时,执行这个函数
this.setData({
sum: numberA + numberB
})
}
}
})
1.2 用作watch
observers: {属性A.keyName: () {...}}
使用通配符**监听所有属性的变化
Component({
observers: {
'some.subfield': function(subfield) {
// 使用 setData 设置 this.data.some.subfield 时触发
// (除此以外,使用 setData 设置 this.data.some 也会触发)
subfield === this.data.some.subfield
},
'arr[12]': function(arr12) {
// 使用 setData 设置 this.data.arr[12] 时触发
// (除此以外,使用 setData 设置 this.data.arr 也会触发)
arr12 === this.data.arr[12]
},
}
})
2. 使用纯数据字段
当某些
data
中的字段(包括setData
设置的字段)既不会展示在界面上,也不会传递给其他组件,仅仅在当前组件内部使用。指定“纯数据字段”的方法是在
Component
构造器的options
定义段中指定pureDataPattern
为一个正则表达式,字段名符合这个正则表达式的字段将成为纯数据字段。数据监听器 可以用于监听纯数据字段(与普通数据字段一样)。
Component({
options: {
pureDataPattern: /^_/
},
data: {
_c: true, // 纯数据字段
}
properties: {
a: Boolean,
_b: {
type: Boolean,
observer() {
// 不要这样做!这个 observer 永远不会被触发
}
},
}
})
setData的使用
1. 对象
// 新增
this.setData({
'user.name': 'Tom',
'user.age': 19
})
// 删除
const {age, name, ...rest} = this.data.user;
this.setData({user: rest})
2. 数组
// 修改
this.setData({
'list[1]': 'Tom', // 普通数组
'list[1].age': 19 // 对象数组
})
总结:
每次 setData 都会触发逻辑层虚拟 DOM 树的遍历和更新,也可能会导致触发一次完整的页面渲染流程。合理使用setData非常的重要哦~