Pinia
前言:
Pinia其目的是设计一个拥有组合式API的Vue状态管理库。并且不强制要求开发者使用组合式API。
- 基本用法:
为什么这里通过ref声明的代理不需要使用.value来进行访问呢?
核心原因:Pinia帮你做了"拆箱",当你从Store中导出count时,Pinia会自动处理这个ref。在Store内部,它是一个标准的ref,你修改它时必须用count.value++。但在组件中,当你通过const store = useCounterStore()拿到它时,Pinia已经把这些属性挂载到store这个响应式对象上了。
由于store本身是一个通过reactive包装的对象,根据Vue的底层规则:当一个ref作为reactive对象的属性时,它会自动解包。
开始
注册Pinia
Store是什么
Store(如pinia)是一个保存状态和业务逻辑的实体,它并不与你得组件树绑定。换句话说,它承载着全局状态。它有点像一个永远存在的组件,每个组件都可以读取和写入它。它有三个概念,state、getter和action,我们可以假设这些概念相当于组件中的data、computed和methods。
核心概念
1. 定义Store
在深入研究核心概念之前,我们得知道 Store 是用 defineStore() 定义的,它的第一个参数要求是一个独一无二的名字:
-
这个名字 ,
也被用作 id,是必须传入的,Pinia将用它来连接store和devtools。为了养成习惯性的用法,将返回的函数命名为use...是一个符合组合式函数风格的约定。 -
defineStore()的第二个参数可接受两类值:Setup函数或Option对象。
Setup Store
Options Store略过,需要自行查阅官方文档。
- 在
Setup Store中:ref()就是state属性,computed()就是getters,function()就是actions。
要让 pinia 正确识别 state,你必须在 setup store 中返回 state的所有属性。这意味着,你不能在store中使用私有属性。不完整返回会影响 SSR ,开发工具和其他插件的正常运行。
Setup store 比 Option Store 带来了更多的灵活性,因为你可以在一个 store 内创建侦听器,并自由地使用任何组合式函数。不过,请记住,使用组合式函数会让 SSR 变得更加复杂。
如果我真的想要"私有"怎么处理
如果你觉得某个变量暴露给组件很危险,或者不希望组件误改它,常见的做法是:依然在Store中返回它,但在命名上做约定(比如加下划线),或者只暴露readonly的版本:
setup store 也可以依赖于全局提供的属性,比如路由。任何应用层面提供的属性都可以在 store 中使用 inject() 访问,就像在组件中一样:
不要返回像 route 或 appProvided (上例中)之类的属性,因为它们不属于 store,而且你可以在组件中直接用 useRoute() 和 inject('appProvided') 访问。
使用Store
-
你可以定义
任意多的store,但为了让使用pinia的益处最大化(比如允许构建工具自动进行代码分割以及TypeScript推断),你应该在不同的文件中去定义store。 -
一旦
store被实例化,你可以直接访问在store的state、getters和actions中定义的任何属性。我们将在后续章节继续了解这些细节,目前自动补全将帮助你使用相关属性。 -
请注意,
store是一个用reactive包装的对象,这意味着不需要在getters后面写.value。就像setup中的props一样,我们不能对它进行解构:
从 Store 解构
为了从 store 中提取属性时保持其响应性,你需要使用 storeToRefs()。它将为每一个响应式属性创建引用。当你只使用 store 的状态而不调用任何 action 时,它会非常有用。请注意,你可以直接从 store 中解构 action,因为它们也被绑定到 store 上:

