微信小程序的状态管理和跨页通讯

小程序开发原生框架是足够好的,唯一缺点就是没有一个全局状态管理和跨页通讯的工具。

针对微信小程序的状态管理,接触使用github上如下的插件库

  • Westore —— 1KB javascript覆盖状态管理、跨页通讯、插件开发和云数据库开发
  • OMIX 2.0 —— westore 的进化版

Westore

文件结构

微信小程序的状态管理和跨页通讯_第1张图片

项目结构只是加了在utils里面的diff.js、create.js以及store.js。里面的diff是核心的库文件,create主要是页面注册用的,而store就是管理全局的数据中心。

API

Westore API 只有六个, 大道至简:

  • create(store, option) 创建页面
  • create(option) 创建组件
  • this.update([data]) 更新页面或组件,其中 data 为可选,data 的格式和 setData 一致
  • store.update([data]) 更新页面或组件,在非页面非组件的 js 文件中使用
  • store.method(path, fn) 更新或扩展函数属性,注意这里不能直接赋值的方式修改函数属性,需要使用 store.method
  • store.onChange = fn 监听 store data 的变化回调,一般可在里面写一些上报或监控数据变化的其他公共逻辑

纯组件使用小程序自带的 Component,或使用 create({ pure: true })。create的方式可以使用 update 方法,Component 方式不行。

创建页面

import store from '../../store'
import create from '../../utils/create'

const app = getApp()

create(store, {
  //只是用来给 westore 生成依赖 path 局部更新
  data: {
    motto: null,
    userInfo: null,
    hasUserInfo: null,
    canIUse: null,
    b: { arr: [ ] },
    firstName: null,
    lastName: null,
    fullName: null,
    pureProp: null
  },
  onLoad: function () {
    if (app.globalData.userInfo) {
      this.store.data.userInfo = app.globalData.userInfo
      this.store.data.hasUserInfo = true
      this.update()
    } else if (this.data.canIUse) {
      app.userInfoReadyCallback = res => {
        this.store.data.userInfo = res.userInfo
        this.store.data.hasUserInfo = true
        this.update()
      }
    } else {
      wx.getUserInfo({
        success: res => {
          app.globalData.userInfo = res.userInfo
          this.store.data.userInfo = res.userInfo
          this.store.data.hasUserInfo = true
          this.update()
        }
      })
    }
  }

})

创建 Page 只需传入两个参数,store 从根节点注入,所有子组件都能通过 this.store 访问。

绑定数据

<view class="container">

  <view class="userinfo">
    <button wx:if="{{!hasUserInfo && canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo"> 获取头像昵称 </button>
    <block wx:else>
      <image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image>
      <text class="userinfo-nickname">{{userInfo.nickName}}</text>
    </block>
  </view>
  <view class="usermotto">
    <text class="user-motto">{{motto}}</text>
  </view>
  <view>{{fullName}}</view>
  <hello></hello>
</view>

和以前的写法没有差别,直接把 store.data 作为绑定数据源。
data 的函数属性也可以直接绑定,但别忘了要在页面上声明相应的函数属性依赖。

更新页面

this.store.data.any_prop_you_want_to_change = 'any_thing_you_want_change_to'
this.update()

创建组件

import create from '../../utils/create'

create({
  ready: function () {
   //you can use this.store here
  },

  methods: {
    //you can use this.store here
  }
})

和创建 Page 不一样的是,创建组件只需传入一个参数,不需要传入 store,因为已经从根节点注入了。

更新组件

this.store.data.any_prop_you_want_to_change = 'any_thing_you_want_change_to'
this.update()

跨页面同步数据

使用 westore 你不用关心跨页数据同步,你只需要专注 this.store.data 便可,修改完在任意地方调用 update 便可:

this.update()

setData 和 update 对比

拿官方模板示例的 log 页面作为例子:

this.setData({
  logs: (wx.getStorageSync('logs') || []).map(log => {
    return util.formatTime(new Date(log))
  })
}, () => {
  console.log('setData完成了')
})

使用 westore 后:

this.store.data.logs = (wx.getStorageSync('logs') || []).map(log => {
  return util.formatTime(new Date(log))
})
this.update().then(diff => {
  console.log('setData完成了')
  console.log('更新内容为', diff)
})

看似一条语句变成了两条语句,但是 this.update 调用的 setData 是 diff 后的,所以传递的数据更少。

OMIX 2.0

OMIX 2.0 是 westore 的进化版,westore 使用的是数据变更前后的 diff,diff 出的 json 就是 setData 的 patch,omix 2.0 使用的是 observer 监听数据的变更得到 setData 的 patch。 和 omix 对比,westore 运行时需要更多的计算,omix 初始化时需要更多的内存和计算,但是数据变更时 omix 速度比 westore 快,编程体验方面,omix 不需要手动 update,westore 需要手动 update。

OMIX 2.0

你可能感兴趣的:(微信小程序)