npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

mobx-miniprogram-bindings

v5.0.0

Published

Mobx binding utils for WeChat miniprogram

Downloads

406

Readme

小程序的 MobX 绑定辅助库

小程序的 MobX 绑定辅助库。

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

使用方法

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

具体的示例完整代码,可以参考 examples

  1. 安装 mobx-miniprogrammobx-miniprogram-bindings
npm install --save mobx-miniprogram mobx-miniprogram-bindings
  1. 创建 MobX Store。
// store.js
import { observable, action } from 'mobx-miniprogram'

// 创建 store 时可以采用任何 mobx 的接口风格
// 这里以传统的 observable 风格为例

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
  }),
})
  1. 在 Page 或 Component 构造器中使用:
import { storeBindingsBehavior } from 'mobx-miniprogram-bindings'
import { store } from './store'

Component({
  behaviors: [storeBindingsBehavior], // 添加这个 behavior
  data: {
    someData: '...',
  },
  storeBindings: {
    store,
    fields: {
      numA: () => store.numA,
      numB: (store) => store.numB,
      sum: 'sum',
    },
    actions: {
      buttonTap: 'update',
    },
  },
  methods: {
    myMethod() {
      this.data.sum // 来自于 MobX store 的字段
    },
  },
})

TypeScript 接口

在 TypeScript 下,可以使用 ComponentWithStore 接口。它会自动处理一些类型问题。注意:

  • 使用这个接口时,不要在 behaviors 中额外引入 storeBindingsBehavior
  • fieldsactions 末尾需要加上 as const 以便更好的类型推导;
  • storeBindings 如果是一个数组,也要在数组后加上 as const
import { ComponentWithStore } from 'mobx-miniprogram-bindings'

ComponentWithStore({
  data: {
    someData: '...',
  },
  storeBindings: {
    store,
    fields: ['numA', 'numB', 'sum'] as const,
    actions: {
      buttonTap: 'update',
    } as const,
  },
})

BehaviorWithStore 接口类似。

import { BehaviorWithStore } from 'mobx-miniprogram-bindings'

export const testBehavior = BehaviorWithStore({
  storeBindings: {
    store,
    fields: ['numA', 'numB', 'sum'] as const,
    actions: ['update'] as const,
  },
})

目前 TypeScript 接口定义依赖于 miniprogram-api-typings ^4.0.0 。 (如使用老版本的 api-typings ,请使用本项目的 v4 或 v3 版本。)

glass-easel Chaining API 接口

使用 glass-easel Chaining API 时,使用 initStoreBindings 更友好。

import { initStoreBindings } from 'mobx-miniprogram-bindings'

Component()
  .init((ctx) => {
    const { listener } = ctx
    initStoreBindings(ctx, {
      store,
      fields: ['numA', 'numB', 'sum'],
    })
    const buttonTap = listener(() => {
      store.update()
    })
    return { buttonTap }
  })
  .register()

具体接口说明

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

behavior 绑定

behavior 绑定 适用于 Component 构造器。做法:使用 storeBindingsBehavior 这个 behavior 和 storeBindings 定义段。

import { storeBindingsBehavior } from 'mobx-miniprogram-bindings'

Component({
  behaviors: [storeBindingsBehavior],
  storeBindings: {
    /* 绑定配置(见下文) */
  },
})

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

import { storeBindingsBehavior } from 'mobx-miniprogram-bindings'

Component({
  behaviors: [storeBindingsBehavior],
  storeBindings: [
    {
      /* 绑定配置 1 */
    },
    {
      /* 绑定配置 2 */
    },
  ],
})

手工绑定

手工绑定 更加灵活,适用于 store 需要在 onLoad (自定义组件 attached )时才能确定的情况。

做法:使用 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' })