Skip to content
On this page

Anim Watch 数据监听

原生小程序只有在组件侧提供了一个 observer 作为监听数据变化的能力,但在页面级别上是缺失了该能力的,Anim 集成的官方维护的 miniprogram-computed 除了提供 computed 计算属性外,还可以支持 watch 数据监听能力。

能力接入

Anim 支持两种构造器对 watch 数据监听的接入。

注意:变量命名 $ 开头会导致监听失效,请避免以此来命名。

页面接入

js
// /pages/index/index.js
import Anim from '@ssv-lab/anim';

Anim.Page({
  data: {
    dataCount: 1,
    newCount: 0,
  },
  watch: {
    dataCount: function (newVal) {
      this.setData({
        newCount: newVal,
      });
    },
  },
  updateCount() {
    this.setData({ dataCount: this.data.dataCount + 1 });
  },
});
html
<!-- /pages/index/index.wxml -->
<view>
  <view>Count: {{dataCount}}</view>
  <view>WatchCount: {{newCount}}</view>
  <view><button bindtap="updateCount">+1</button></view>
</view>

组件接入

js
// /components/A/A.js
import Anim from '@ssv-lab/anim';

Anim.Component({
  data: {
    dataCount: 1,
    newCount: 0,
  },
  watch: {
    dataCount: function (newVal) {
      this.setData({
        newCount: newVal,
      });
    },
  },
  methods: {
    updateCount() {
      this.setData({ dataCount: this.data.dataCount + 1 });
    },
  },
});
html
<!-- /components/A/A.wxml -->
<view>
  <view>Count: {{dataCount}}</view>
  <view>WatchCount: {{newCount}}</view>
  <view><button bindtap="updateCount">+1</button></view>
</view>

在 watch 的函数中,如果需要改变绑定 UI 的数据是需要手动进行 this.setData,这里要防止出现死循环的情况。

Watch 多个数据

Anim 的 watch 可以同时监听多个数据,任意一个数据变化了都会触发到 watch 函数。

js
// /pages/index/index.js
import Anim from '@ssv-lab/anim';

Anim.Page({
  data: {
    a: 1,
    b: 2,
  },
  watch: {
    'a, b': function (...changes) {
      // 得到 [a, b]
      console.log('changes', changes);
    },
  },
  updateCount() {
    this.setData({
      a: this.data.a + 1,
      b: this.data.b + 1,
    });
  },
});

通配符监听

watch 字段上可以使用 ** 通配符,是它能够监听这个字段下的子字段的变化(类似于小程序基础库本身的 observers )。

js
const computedBehavior = require('miniprogram-computed').behavior;

Component({
  behaviors: [computedBehavior],
  data: {
    obj: {
      a: 1,
      b: 2,
    },
  },
  watch: {
    'obj.**': function (obj) {
      this.setData({
        sum: obj.a + obj.b,
      });
    },
  },
  methods: {
    onTap() {
      this.setData({
        'obj.a': 10,
      });
    },
  },
});

除此以外:

  • 对于没有使用 ** 通配符的字段,在 watch 检查值是否发生变化时,只会进行粗略的浅比较(使用 === );
  • 对于使用了 ** 通配符的字段,则会进行深比较,来尝试精确检测对象是否真的发生了变化,这要求对象字段不能包含循环(类似于 JSON.stringify )。

Watch 与 Store 的使用

Anim 支持直接监听 store 的数据,需要注意的是当我们需要监听深层数据变化时,需要加上通配符。

js
// /pages/index/index.js
import Anim from '@ssv-lab/anim';
import countStore from '../../store/countStore';

Anim.Page({
  data: {
    dataCount: 1,
  },
  store: {
    counter: countStore,
    userInfo: userStore,
  },
  watch: {
    'counter.count': function (newVal) {
      console.log('store change', newVal);
    },
    'userInfo.**': function (newVal) {
      console.log('store change', newVal);
    },
  },
});

关于更多关于 Store 的使用,请参照 Anim Store 一栏。

Released under the MIT License.