close
The Wayback Machine - https://web.archive.org/web/20210815075725/https://github.com/wechat-miniprogram/computed
Skip to content
master
Switch branches/tags
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
src
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

computed

小程序自定义组件扩展 behavior,计算属性 computed 和监听器 watch 的实现。在 data 或者 properties 改变时,会重新计算 computed 字段并触发 watch 监听器。

此 behavior 依赖开发者工具的 npm 构建。具体详情可查阅官方 npm 文档

注意: 4.0.0 大版本变更了最基本的接口名,升级到 4.0.0 以上时请注意 #60 的问题。旧版文档可以参考对应版本的 git tag 中的 README ,如 v3.1.1 tag 。

使用方法

方式一 代码片段

需要小程序基础库版本 >= 2.6.1 的环境。

可以直接体验一下这个代码片段,它包含了基本用法示例:https://developers.weixin.qq.com/s/UqMytwmF7Gni

体验该代码片段前,需要先安装并构建相对应的 npm 包。

npm install --save miniprogram-computed

方式二 本地构建

将本仓库 clone 到本地,进入根目录安装 npm 依赖。

npm install

安装完成后执行

npm run dev // 构建 dev 版本

构建完毕后,根目录下的 miniprogram_dev 即为小程序代码根目录,可以将此 demo 导入开发者工具中进行体验。

computed 基本用法

// component.js
const computedBehavior = require('miniprogram-computed').behavior
const behaviorTest = require('./behavior-test') // 引入自定义 behavior

Component({
  behaviors: [behaviorTest, computedBehavior],
  data: {
    a: 1,
    b: 1,
  },
  computed: {
    sum(data) {
      // 注意: computed 函数中不能访问 this ,只有 data 对象可供访问
      // 这个函数的返回值会被设置到 this.data.sum 字段中
      return data.a + data.b + data.c // data.c 为自定义 behavior 数据段
    },
  },
  methods: {
    onTap() {
      this.setData({
        a: this.data.b,
        b: this.data.a + this.data.b,
      })
    }
  }
})
//behavior-test.js
module.exports = Behavior({
  data: {
    c: 2,
  }
})
<view>A = {{a}}</view>
<view>B = {{b}}</view>
<view>SUM = {{sum}}</view>
<button bindtap="onTap">click</button>

watch 基本用法

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

Component({
  behaviors: [computedBehavior],
  data: {
    a: 1,
    b: 1,
    sum: 2,
  },
  watch: {
    'a, b': function(a, b) {
      this.setData({
        sum: a + b
      })
    },
  },
  methods: {
    onTap() {
      this.setData({
        a: this.data.b,
        b: this.data.a + this.data.b,
      })
    }
  }
})
<view>A = {{a}}</view>
<view>B = {{b}}</view>
<view>SUM = {{sum}}</view>
<button bindtap="onTap">click</button>

TypeScript支持

由于通过behavior的方式引入不能获得类型支持, 因此为了获得类型的支持, 可以使用一个辅助组件构造器:

import { ComponentWithComputed } from 'miniprogram-computed'

ComponentWithComputed({
  data: {
    a: 1,
    b: 1,
    sum: 2,
  },
  watch: {
    'a, b': function(a, b) {
      this.setData({
        sum: a + b
      })
    },
  },
  computed: {
    sum(data) {
      // 注意: computed 函数中不能访问 this ,只有 data 对象可供访问
      // 这个函数的返回值会被设置到 this.data.sum 字段中
      return data.a + data.b + data.sum // data.c 为自定义 behavior 数据段
    },
  }
})

当使用该构造器的时候, 编译器可以给 computedwatch 提供自动提示和类型支持。

注意: 当使用该构造器的时候, 无需手动加入 computedBehavior , 该构造器会自动引入该 behavior 。

(类似地,也有 BehaviorWithComputed 构造器对应于 Bahavior 。)

^4.0.0 与 ^1.0.0、 ^2.0.0、 ^3.0.0 版本的差异

^4.0.0 版本

  • 变更了最基本的接口。

  • 新增简单的 TypeScript 支持。

^3.0.0 版本

  • 支持 mobx-miniprogram 扩展库引入的数据段。

  • 对自定义 behavior 数据段使用 computed 时,支持在初始化视图中进行数据渲染。

  • 基于 proxy 更新了 computed 数据追踪的实现方式,computed 依赖的数据路径追踪初始化操作,延后到组件的 created 阶段 。

^2.0.0 版本

基于小程序基础库 2.6.1 开始支持的 observers 定义段实现,具有较好的性能。

以下是版本之间主要区别的比较。

项目 ^1.0.0 ^2.0.0 ^3.0.0 和 ^4.0.0
支持的基础库最低版本 2.2.3 2.6.1 2.6.1
支持 watch 定义段
性能 相对较差 相对较好 相对较好
支持 mobx-miniprogram 扩展库 不支持 不支持 支持
支持自定义 behavior 数据字段 / 初始化视图渲染 不支持 / 不支持 支持 / 不支持 支持 / 支持

常见问题说明

我应该使用 computed 还是 watch ?

从原理上说, watch 的性能比 computed 更好;但 computed 的用法更简洁干净。

此外, computed 字段状态只能依赖于 data 和其他 computed 字段,不能访问 this 。如果不可避免要访问 this ,则必须使用 watch 代替。

watch 和小程序基础库本身的 observers 有什么区别?

  • 无论字段是否真的改变, observers 都会被触发,而 watch 只在字段值改变了的时候触发,并且触发时带有参数。

关于 ** 通配符

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

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 )。

About

小程序自定义组件 computed / watch 扩展

Resources

License

Packages

No packages published