Skip to content
On this page

用户全局状态

基于 Anim Store 的用户全局状态管理方案,提供了一种简单的方式,让用户可以在任意页面和组件中,通过 Anim Store 来获取到全局状态。核心思想是将全局状态转移到一个单独的数据层,通过 Anim Store 来管理这个数据层,从而实现全局状态的共享。而且该数据存储层是响应式的,当数据发生变化时,会自动通知注册了 store 的页面和组件进行 UI 级别的更新。

image-20230403104223978

使用场景

在很多业务中,我们需要在不同页面和组件中,共享用户的一些全局状态,比如用户的登录状态、用户的基本信息等等。在没有使用 Anim Store 的情况下存在一些问题:

  1. 用户信息通常需要存储在组件内部或使用其他数据存储方式,例如 wx.storage 或者 globalData。这样会导致信息存储分散,用户信息的获取和更新变得复杂,不利于维护。
  2. 在没有全局状态库时,组件需要通过props、事件传递等方式来共享用户信息。这样会增加代码复杂度和维护成本,同时可能会导致不必要的数据传输。
  3. 当用户信息数据更新时,需要手动通知页面和组件进行更新,这样会增加代码复杂度和维护成本。

总而言之,全局状态管理库则是为了解决这些问题而诞生的。如果我们使用了 Anim Store 后,我们可以得到以下优点:

  1. 用户信息存储在一个单独的数据层,方便管理和维护。
  2. 所有的页面和组件都可以通过 Anim Store 来获取用户信息,不需要通过props、事件传递等方式。
  3. 绑定了用户信息的页面和组件,当用户信息发生变化时,会自动更新,不再需要用户手动更新 data 数据。

以下是一些最佳实践

UserStore 的定义

js
// store/user.js

class UserStore {
  data: {
    // 用户信息
    userInfo: null,
  },

  // 用于提供给 JS 判断用户是否登录
  isLogin() {
    return !!this.data.userInfo
  },

  // 更新用户信息
  updateUserInfo(userInfo) {
    if(userInfo) {
      this.data.userInfo = userInfo
      // 更新数据后,需要调用 update 方法,通知页面和组件进行更新
      this.update()
    }
  }
}

export default new UserStore()

1. 页面使用了用户信息

首先我们绑定 UserStore

js
// pages/index/index.js
import Anim from '@ssv-lab/anim'
import userStore from '../../store/user'

Anim.Page({
  store: {
    // store key 必须以 $ 开头
    $user: userStore
  }
})

然后就可以在 wxml 中使用了

html
<!-- pages/index/index.wxml -->
<view class="user-info">
  <view class="name">{{ $user.data.userInfo.name }}</view>
</view>

2. 组件使用了用户信息

使用方式同上,只是需要换成 Anim.Component 中绑定 store

js
// components/user-info/user-info.js
import Anim from '@ssv-lab/anim'
import userStore from '../../store/user'

Anim.Component({
  store: {
    $user: userStore
  }
})

3. 在 JS 逻辑中使用用户信息

js
// pages/index/index.js
import Anim from '@ssv-lab/anim'
import userStore from '../../store/user'

Anim.Page({
  store: {
    $user: userStore
  },

  onLoad() {
    // 判断用户是否登录
    if(userStore.isLogin()) {
      // do something
    }
  }
})

4. 结合 Anim Storecomputed 使用

js
// pages/index/index.js
import Anim from '@ssv-lab/anim'
import userStore from '../../store/user'
Anim.Page({
  store: {
    $user: userStore
  },
  computed: {
    // 脱敏手机号展示
    securePhone(data) {
      return data.$user.userInfo?.PhoneNumber.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2')
    }
  }
})
html
<!-- pages/index/index.wxml -->
<view class="user-info">
  <view class="name">{{ $user.userInfo?.name }}</view>
  <view class="phone">{{ securePhone }}</view>
</view>

Released under the MIT License.