小程序中的setData

103 阅读3分钟

setData

这是小程序再逻辑层用于设置页面数据的API

setData函数用于将数据从逻辑层发送到视图层(异步),同时改变对应的this.data的值(同步)

1. setData更新的过程

  1. 逻辑层虚拟 DOM 树的遍历和更新,触发组件生命周期和 observer 等
  2. 逻辑层把修改后的 data 通过 setData 传到渲染层
  3. 渲染层会根据渲染机制重新生成 VD(虚拟 DOM)树,并更新到对应的 DOM 树上,引起界面变化
  • 小程序的视图层目前使用 WebView 作为渲染载体,而逻辑层是由独立的 JavascriptCore 作为运行环境。
  1. 渲染层中使用双括号语法(带有数据绑定语法的DSL)来描述页面的结构
<view>{{ message }}</view>

2. 当用户按下按钮的时候发生了什么?

通信过程:

  1. 渲染层 -> Native(点击事件)。
  2. Native -> 逻辑层(点击事件)。
  3. 逻辑层 -> Native(setData)。(原生组件可以绕过setData)
  4. 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非常的重要哦~