pinia

N_Vue3 全家桶

Pinia 起始 于 2019 年 11 月左右的一次实验,其目的是设计一个拥有组合式 API 的 Vue 状态管理库。从那时起,我们就倾向于同时支持 Vue 2 和 Vue 3,并且不强制要求开发者使用组合式 API,我们的初心至今没有改变。

Pinia 是 Vue 的专属状态管理库,它允许你跨组件或页面共享状态。如果你熟悉组合式 API 的话,你可能会认为可以通过一行简单的 export const state = reactive({}) 来共享一个全局状态。对于单页应用来说确实可以,但如果应用在服务器端渲染,这可能会使你的应用暴露出一些安全漏洞。

https://pinia.vuejs.org/zh/introduction.html

实例

核心概念

定义 Store

‘counter’ 这个名字 ,也被用作 id ,是必须传入的, Pinia 将用它来连接 store 和 devtools。为了养成习惯性的用法,将返回的函数命名为 use… 是一个符合组合式函数风格的约定。

import { defineStore } from 'pinia'
// 你可以对 `defineStore()` 的返回值进行任意命名,但最好使用 store 的名字,同时以 `use` 开头且以 `Store` 结尾。(比如 `useUserStore`,`useCartStore`,`useProductStore`)
// 第一个参数是你的应用中 Store 的唯一 ID。
export const useAlertsStore = defineStore('counter', {
  // 其他配置...
})

其他配置 (Option Store)

export const useCounterStore = defineStore('counter', {
  state: () => ({ count: 0 }),//store 的数据
  getters: {//store 的计算属性
    double: (state) => state.count * 2,
  },
  actions: {//store 的操作方法
    increment() {
      this.count++
    },
  },
})

你可以认为 

  • state 是 store 的数据 (data),
  • getters 是 store 的计算属性 (computed),
  • actions 则是方法 (methods)。

组合式API

export const useCounterStore = defineStore('counter', () => {
  const count = ref(0)
  function increment() {
    count.value++
  }
  return { count, increment }
})

在 Setup Store 中:

  • ref() 就是 state 
  • computed() 就是 getters
  • function() 就是 actions

操作 state

访问 state

默认情况下,你可以通过 store 实例访问 state,直接对其进行读写。

const store = useStore()
 
store.count++

修改部分 state

除了用 store.count++ 直接改变 store,你还可以调用 $patch 方法。它允许你用一个 state 的补丁对象在同一时间更改多个属性:

store.$patch({
  count: store.count + 1,
  age: 120,
  name: 'DIO',
})

修改全部 state

你也可以通过变更 pinia 实例的 state 来设置整个应用的初始 state。

pinia.state.value = {}

重置 state

使用选项式 API 时,你可以通过调用 store 的 $reset() 方法将 state 重置为初始值。

const store = useStore()
store.$reset()

订阅 state

类似于 Vuex 的 subscribe 方法,你可以通过 store 的 $subscribe() 方法侦听 state 及其变化。比起普通的 watch(),使用 $subscribe() 的好处是 subscriptions 在 patch 后只触发一次

cartStore.$subscribe((mutation, state) => {
  // import { MutationType } from 'pinia'
  mutation.type // 'direct' | 'patch object' | 'patch function'
  // 和 cartStore.$id 一样
  mutation.storeId // 'cart'
  // 只有 mutation.type === 'patch object'的情况下才可用
  mutation.payload // 传递给 cartStore.$patch() 的补丁对象。
  // 每当状态发生变化时,将整个 state 持久化到本地存储。
  localStorage.setItem('cart', JSON.stringify(state))
})