微信小程序-状态管理和计算属性

mobx-miniprogram(状态管理)

mobx-miniprogram 是针对微信小程序开发的一个简单、高效、轻量级状态管理库,为了方便进行页面、组件之间数据的传递,它基于Mobx状态管理框架实现。

使用 mobx-miniprogram 定义管理的状态是响应式的,当状态一旦它改变,所有关联组件都会自动更新相对应的数据

通过该扩展工具库,开发者可以很方便地在小程序中全局共享的状态,并自动更新视图组件,从而提升小程序的开发效率

在使用 mobx-miniprogram 需要安装两个包:mobx-miniprogrammobx-miniprogram-bindings

  1. mobx-miniprogram 的作用:创建 Store 对象,用于存储应用的数据。
  2. mobx-miniprogram-bindings 的作用:将状态与组件、页面进行绑定关联,从而在组件和页面中操作数据。

官方文档:

  1. mobx-miniprogram 官方文档

  2. mobx-miniprogram-bindings 官方文档

安装包

npm install mobx-miniprogram mobx-miniprogram-bindings

创建Store对象

import { observable, action } from "mobx-miniprogram"

// 创建observable对象,用于被监测的对象,具有响应式特性
export const numStore = observable({
    // 定义状态
    numA: 1,
    numB: 2,
    // 定义更新状态的方法
    updateNumA: action(function () {
        this.numA += 1
    }),
    updateNumB: action(function () {
        this.numB += 1
    }),
    // 定义计算属性
    // 需要使用get修饰符,必须有返回值
    get sum() {
        return this.numA + this.numB
    },
})

在组件中使用

  • 将 Component 方法替换为 ComponentWithStore 方法。
  • 使用 storeBindings 选项关联 store 实例:
    • store:指定需要绑定的store对象。
    • fields:指定需要使用store对象的数据。
    • actions:指定需要使用store对象的方法。
  • 注入关系:
    • fields会被注入到data对象中。
    • actions会被注入到methods对象中。
    • 因此可以直接在wxml中使用fields和actions中定义的属性。
import { ComponentWithStore } from "mobx-miniprogram-bindings"
import { numStore } from "../../store/numStore.js"

ComponentWithStore({
  // 绑定store对象
  storeBindings: {
    store: numStore,
    fields: ["numA", "numB", "sum"],
    actions: ["updateNumA", "updateNumB"],
  },
})
<view>
  {{numA}} + {{numB}} = {{sum}}
</view>
<button bindtap="updateNumA">更新numA</button>
<button bindtap="updateNumB">更新numB</button> 

在页面中使用

import { ComponentWithStore } from "mobx-miniprogram-bindings"
import { numStore } from "../../store/numStore"

ComponentWithStore({
  storeBindings: {
    store: numStore,
    fields: ["numA", "numB", "sum"],
    actions: ["updateNumA", "updateNumB"],
  },
})
<view>
  {{numA}} + {{numB}} = {{sum}}
</view>
<button bindtap="updateNumA">更新numA</button>
<button bindtap="updateNumB">更新numB</button>

BehaviorWithStore

behavior 方法是一种代码复用方式,可以将一些通用的逻辑和方法提取出来,在多个组件中复用。

Page 方法支持 behaviors 配置项。

步骤:

  1. 新建 behavior 文件
  2. 使用 BehaviorWithStore 函数并配置。
  3. 在 Page 中使用 behavior。
import { BehaviorWithStore } from "mobx-miniprogram-bindings"
import { numStore } from "../store/numStore"

export const indexBehavior = BehaviorWithStore({
  storeBindings: {
    store: numStore,
    fields: ["numA", "numB", "sum"],
    actions: ["updateNumA", "updateNumB"],
  },
})
import { indexBehavior } from "../../behavior/indexBehavior"

Page({
  behaviors: [indexBehavior],
})

field/actions其他写法

fields 有三种形式:

fields: ['numA', 'numB', 'sum'] // 数组形式

fields: {a: "numA", b: "numB", c: "sum"} // 映射形式

fields: {a: () => numStore.numA, b: () => numStore.numB, c: () => numStore.sum} // 函数形式

actions 有两种形式:

actions: ["updateNumA", "updateNumB"] // 数组形式

actions: {updateA: "updateNumA", updateB: "updateNumB"} // 映射形式    

命名空间

当一个页面或组件绑定多个 Store 时,将 storeBindings 改为数组,再添加 namespace 选项给 Store 对象添加命名空间,访问数据时用 namespace 区分。

// 绑定多个store
export const indexBehavior = BehaviorWithStore({
    storeBindings: [
        {
            namespace: "numStore",
            store: numStore,
            fields: ["numA", "numB", "sum"],
            actions: ["updateNumA", "updateNumB"],
        }
    ]
})
<view>
  {{numStore.numA}} + {{numStore.numB}} = {{numStore.sum}}
</view>
<button bindtap="updateNumA">更新numA</button>
<button bindtap="updateNumB">更新numB</button>

miniprogram-computed(计算属性)

miniprogram-computed 是官方为开发者提供的一个计算属性的框架。

提供了两个功能:

  • computed:计算属性,具有缓存功能。
  • watch:监听器。

安装包

npm install miniprogram-computed

使用

将 Page/Component 方法替换成 ComponentWithComputed 方法。

computed 属性不能访问 this,但是提供形参代表 data 对象。

使用计算属性:

import { ComponentWithComputed } from "miniprogram-computed"

ComponentWithComputed({
  data: {
    a: 1,
    b: 2,
  },
  methods: {
    updateData() {
      this.setData({
        a: this.data.a + 1,
        b: this.data.b + 1,
      })
    },
  },
  // 计算属性
  computed: {
    total(data) {
      return data.a + data.b
    },
  }
})

<text>{{a}} + {{b}} = {{total}}</text>
<button bindtap="updateData">修改</button>

使用监听器:

import { ComponentWithComputed } from "miniprogram-computed"
ComponentWithComputed({
  data: {
    a: 1,
    b: 2,
    c: 0,
  },
  methods: {
    updateData() {
      this.setData({
        a: this.data.a + 1,
        b: this.data.b + 1,
      })
    },
  },
  // 监听器
  watch: {
    "a,b": function (a, b) {
      this.setData({
        c: a + b,
      })
    },
  },
  lifetimes: {
    attached() {
      console.log("Component attached")
      this.setData({
        c: this.data.a + this.data.b,
      })
    },
  },
})
<text>{{a}} + {{b}} = {{c}}</text>
<button bindtap="updateData">修改</button>

Mobx和Computed结合使用

两个框架扩展提供的 ComponentWithStoreComponentWithComputed 方法无法结合使用。

同时使用解决方法:

  • 使用旧版API
  • 使用兼容写法
    • 即要么使用 ComponentWithStore 方法构建组件,要么使用 ComponentWithComputed 方法构建组件
    • 如果使用了 ComponentWithStore 方法构建组件,计算属性写法使用旧版 API
    • 如果使用了 ComponentWithComputed 方法构建组件,Mobx写法使用旧版 API

使用ComponentWithStore时

import { ComponentWithStore } from "mobx-miniprogram-bindings"
import { numStore } from "../../store/numStore.js"

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

ComponentWithStore({
  behaviors: [computedBehavior],
  data: { a: 1, b: 2 },
  methods: {
    updateData() {
      this.setData({
        a: this.data.a + 1,
        b: this.data.b + 1,
      })
    },
  },
  // 监听器
  watch: {
    "a,b": function (a, b) {
      this.setData({})
    },
  },
  // 计算属性
  computed: {
    total(data) {
      return data.a + data.b
    },
  },
  // 关联store
  storeBindings: {
    store: numStore,
    fields: ["numA", "numB", "sum"],
    actions: ["update"],
  },
})

使用ComponentWithComputed时

import { ComponentWithComputed } from "miniprogram-computed"
import { storeBindingsBehavior } from "mobx-miniprogram-bindings"
import { numStore } from "../../store/numStore.js"

ComponentWithComputed({
  behaviors: [storeBindingsBehavior],
  data: { a: 1, b: 2 },
  methods: {
    updateData() {
      this.setData({
        a: this.data.a + 1,
        b: this.data.b + 1,
      })
    },
  },
  // 监听器
  watch: {
    "a,b": function (a, b) {
      this.setData({})
    },
  },
  // 计算属性
  computed: {
    total(data) {
      return data.a + data.b
    },
  },
  // 关联store
  storeBindings: {
    store: numStore,
    fields: ["numA", "numB", "sum"],
    actions: ["update"],
  },
})
Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐