Pinia状态管理工具

Pinia状态管理工具
LiSir简介
Pinia 起始于 2019 年 11 月左右的一次实验,其目的是设计一个拥有组合式 API 的 Vue 状态管理库。从那时起,我们就倾向于同时支持 Vue 2 和 Vue 3,并且不强制要求开发者使用组合式 API,我们的初心至今没有改变。除了安装和 SSR 两章之外,其余章节中提到的 API 均支持 Vue 2 和 Vue 3。虽然本文档主要是面向 Vue 3 的用户,但在必要时会标注出 Vue 2 的内容,因此 Vue 2 和 Vue 3 的用户都可以阅读本文档。
开始
安装
用你喜欢的包管理器安装 pinia:
1 | yarn add pinia |
创建一个 pinia 实例 (根 store) 并将其传递给应用:
1 | import { createApp } from 'vue' |
Store 是什么?
Store (如 Pinia) 是一个保存状态和业务逻辑的实体,它并不与你的组件树绑定。换句话说,它承载着全局状态。它有点像一个永远存在的组件,每个组件都可以读取和写入它。它有三个概念,state、getter 和 action,我们可以假设这些概念相当于组件中的 data、 computed 和 methods。
定义 Store
在深入研究核心概念之前,我们得知道 Store 是用 defineStore() 定义的,它的第一个参数要求是一个独一无二的名字:
1 | import { defineStore } from 'pinia' |
defineStore() 的第二个参数可接受两类值:Setup 函数或 Option 对象。
类似于选项式定义Store
与 Vue 的选项式 API 类似,我们也可以传入一个带有 state、actions 与 getters 属性的 Option 对象
1 | export const useCounterStore = defineStore('counter', { |
你可以认为 state 是 store 的数据 (data),getters 是 store 的计算属性 (computed),而 actions 则是方法 (methods)。
类似于组合式定义Store
与Vue3的组合式API类似,第二个参数可以时类似于setup的函数:比如:
1 | export const useCounterStore = defineStore('counter', |
在这个和函数中
ref()就是state属性computed()就是gettersfunction()就是actions
注意,要将定义的属性返回出去,否则在别的地方使用会无法读取数据。
使用 Store
1 | <script setup> |
注意,store 是一个用 reactive 包装的对象,这意味着不需要在 getters 后面写 .value。就像 setup 中的 props 一样,我们不能对它进行解构:
如何从Store中解构
解构赋值会是数据失去响应性。!!!!
为了从 store 中提取属性时保持其响应性,你需要使用 storeToRefs()。它将为每一个响应式属性创建引用。当你只使用 store 的状态而不调用任何 action 时,它会非常有用。请注意,你可以直接从 store 中解构 action,因为它们也被绑定到 store 上:
1 | <script setup> |
Store上的$subscribe方法
$subscribe方法的作用类似于watch,当store中的数据发生变化时,会触发该函数
1 | TestStore.$subscribe(()=>{ |
效果:
该函数注意点有:
- $subscribe(()=>{}),要传入一个箭头函数,若要使用this,传入常规函数即可
- 该函数可以收到两个参数,
mutate和state,mutate是本次修改的信息,state就是我们在store中定义的state。
State
访问 state
默认情况下,你可以通过 store 实例访问 state,直接对其进行读写。
1 | <template> |
如果你的属性没有定义在state函数中,那么自然也访问不到。
变更 state(修改数据)
1.最基本的方法
1 | //这里拿上边的例子 |
2.$pacth方法
依旧是上面的例子,写法这么写,可以传入一个对象
1 | TestStore.$patch({ |
写法2
针对于对集合的修改,我们也可以传入一个函数来实现
1 | TestStore.$patch((state)=>{ |
3.通过定义Action选项修改
1.首先我们需要在store中配置actions选项
1 | actions:{ |
2.通过store实例调用这个方法(actions)
1 | TestStore.increment() |
Getter
Getter完全等同于store中state的计算值,类似于计算属性
在defineStore函数中定义getters配置项
1 | getters:{ |
1 | //解构赋值 |
1 | <!--页面渲染--> |
效果
Action
Action 相当于组件中的 method。它们可以通过 defineStore() 中的 actions 属性来定义,并且它们也是定义业务逻辑的完美选择。
1 | export const useCounterStore = defineStore('main', { |
组合式定义Store
上面的写法,是选项式写法,下面介绍一些组合式定义Store
注意点有2:
- 在组合式中,我们并不需要去写state,getters,actions,而是用vue中的ref或者reactive定义state中的响应式变量,直接通过
function + 函数名字来定义函数即可。 - 要记得把要用到的数据和方法return出去
- 示例写法如下:
1 | //组合式写法 |





