美文网首页
用mobx-miniprogram-bindings实现小程序的

用mobx-miniprogram-bindings实现小程序的

作者: kevision | 来源:发表于2022-08-31 13:07 被阅读0次

    官方文档:小程序的 MobX 绑定辅助库

    一、使用方法

    1. 安装


    安装 mobx-miniprogrammobx-miniprogram-bindings:

    npm install --save mobx-miniprogram mobx-miniprogram-bindings
    

    2. 创建 MobX Store


    // store.js
    import { observable, action } from "mobx-miniprogram";
    
    export const store = observable({
      // 数据字段
      numA: 1,
      numB: 2,
    
      // 计算属性
      get sum() {
        return this.numA + this.numB;
      },
    
      // actions
      update: action(function () {
        const sum = this.sum;
        this.numA = this.numB;
        this.numB = sum;
      }),
    });
    

    3. 使用


    在 Component 构造器中使用——behavior 绑定
    import { storeBindingsBehavior } from "mobx-miniprogram-bindings";
    import { store } from "./store";
    
    Component({
      behaviors: [storeBindingsBehavior],
      data: {
        someData: "...",
      },
      storeBindings: {
        store,
        // 方式一:数组形式
        // fields: ['numA', 'numB', 'sum'], // --> this.data.numA访问store里面的numA
        // 方式二:普通对象键值对形式
        // fields: {a: 'numA', b: 'numB', sum: 'sum'}, // this.data.a访问store里面的numA
        // 方式三:函数形式
        fields: { // fields里面的属性相当于data里面的属性
          numA: () => store.numA,
          numB: (store) => store.numB,
          sum: "sum",
        },
        // 方式一:数组形式
        // actions: ['update'], --> this.update()调用store里面的update
        // 方式二:对象形式
        actions: { // actions里面的属性相当于methods里面的方法
          buttonTap: "update", // --> this.buttonTap()调用store里面的update
        },
      },
      methods: {
        myMethod() {
          this.data.sum; // 来自于 MobX store 的字段
        },
      },
    });
    
    在 Page 构造器中使用——手工绑定
    import { createStoreBindings } from "mobx-miniprogram-bindings";
    import { store } from "./store";
    
    Page({
      data: {
        someData: "...",
      },
      onLoad() {
        this.storeBindings = createStoreBindings(this, {
          store,
          fields: ["numA", "numB", "sum"],
          actions: ["update"],
        });
      },
      onUnload() {
        this.storeBindings.destroyStoreBindings();
      },
      myMethod() {
        this.data.sum; // 来自于 MobX store 的字段
      },
    });
    

    二、两种绑定方式

    将页面、自定义组件和 store 绑定有两种方式: behavior 绑定手工绑定

    behavior 绑定——适用于组件


    behavior 绑定 适用于 Component 构造器。做法:使用 storeBindingsBehavior 这个 behavior 和 storeBindings 定义段。
    (注意:你可以用 Component 构造器构造页面, 参考文档 。)

    import { storeBindingsBehavior } from "mobx-miniprogram-bindings";
    Component({
      behaviors: [storeBindingsBehavior],
      storeBindings: {
        /* 绑定配置(见下文) */
      },
    });
    

    也可以把 storeBindings 设置为一个数组,这样可以同时绑定多个 store :

    import { storeBindingsBehavior } from "mobx-miniprogram-bindings";
    Component({
      behaviors: [storeBindingsBehavior],
      storeBindings: [
        {
          /* store1绑定配置 */
        },
        {
          /* store2绑定配置 */
        },
      ],
    });
    

    手工绑定——适用于所有


    手工绑定 适用于全部场景。做法:使用 createStoreBindings 创建绑定,它会返回一个包含清理函数的对象用于取消绑定。
    注意:在页面 onUnload (自定义组件 detached )时一定要调用清理函数,否则将导致内存泄漏!

    import { createStoreBindings } from "mobx-miniprogram-bindings";
    
    Page({
      onLoad() {
        this.storeBindings = createStoreBindings(this, {
          /* 绑定配置(见下文) */
        });
      },
      onUnload() {
        this.storeBindings.destroyStoreBindings();
      },
    });
    

    绑定配置


    无论使用哪种绑定方式,都必须提供一个绑定配置对象。这个对象包含的字段如下:

    字段名 类型 含义
    store 一个 MobX observable 默认的 MobX store
    fields 数组或者对象 用于指定需要绑定的 data 字段
    actions 数组或者对象 用于指定需要映射的 actions

    fields

    fields 有三种形式:

    • 数组形式:指定 data 中哪些字段来源于 store 。例如 ['numA', 'numB', 'sum']
    • 映射形式:指定 data 中哪些字段来源于 store 以及它们在 store 中对应的名字。例如 { a: 'numA', b: 'numB' } ,此时 this.data.a === store.numA this.data.b === store.numB
    • 函数形式:指定 data 中每个字段的计算方法。例如 { a: () => store.numA, b: () => anotherStore.numB } ,此时 this.data.a === store.numA this.data.b === anotherStore.numB

    上述三种形式中,映射形式和函数形式可以在一个配置中同时使用。

    如果仅使用了函数形式,那么 store 字段可以为空,否则 store 字段必填。

    actions

    actions 可以用于将 store 中的一些 actions 放入页面或自定义组件的 this 下,来方便触发一些 actions 。有两种形式:

    • 数组形式:例如 ['update'] ,此时 this.update === store.update
    • 映射形式:例如 { buttonTap: 'update' } ,此时 this.buttonTap === store.update

    只要 actions 不为空,则 store 字段必填。

    三、注意事项

    延迟更新与立刻更新


    为了提升性能,在 store 中的字段被更新后,并不会立刻同步更新到 this.data 上,而是等到下个 wx.nextTick 调用时才更新。(这样可以显著减少 setData 的调用次数。)

    如果需要立刻更新,可以调用:

    • this.updateStoreBindings() (在 behavior 绑定 中)
    • this.storeBindings.updateStoreBindings() (在 手工绑定 中)

    与 miniprogram-computed 一起使用


    miniprogram-computed 时,在 behaviors 列表中 computedBehavior 必须在后面:

    Component({
      behaviors: [storeBindingsBehavior, computedBehavior],
      /* ... */
    });
    

    关于部分更新


    如果只是更新对象中的一部分(子字段),是不会引发界面变化的!例如:

    Component({
      behaviors: [storeBindingsBehavior],
      storeBindings: {
        store,
        fields: ["someObject"],
      },
    });
    

    如果尝试在 store 中:

    this.someObject.someField = "xxx";
    

    这样是不会触发界面更新的。请考虑改成:

    this.someObject = Object.assign({}, this.someObject, { someField: "xxx" });
    

    关于store数据修改


    1. 对于在页面和组件里拿到的store数据,可以跟修改data里面的数据一样修改,例如:
    this.storeBindings = createStoreBindings(this, {
        store,
        fields: ["obj"],
        actions: ["update"],
    });
    

    setData进行修改:

    this.setData({
        'obj.name': 'ken'
    })
    
    1. 对于需要在页面和组件间共享的store数据,需要调actions里面的方法修改,例如:
    // store.js
    import { observable, action } from "mobx-miniprogram";
    
    export const store = observable({
      // 数据字段
      account: '1', 
      // 计算属性
      // get sum() {
      //   return this.numA + this.numB;
      // },
    
      // actions
      update: action(function (val) {
        this.account = val
      }),
    });
    
    // 页面或组件中
    handleTap() {
        this.update('xxx')
    }
    

    相关文章

      网友评论

          本文标题:用mobx-miniprogram-bindings实现小程序的

          本文链接:https://www.haomeiwen.com/subject/qtxrnrtx.html