一. Pinia 和 Vuex 的对比
1. 什么是 Pinia 呢?
Pinia
(发音为/piːnjʌ/
,如英语中的“peenya
”)是最接近piña
(西班牙语中的菠萝)的词Pinia
开始于大概2019年,最初是作为一个实验为Vue
重新设计状态管理,让它用起来像组合式API
(Composition API
)从那时到现在,最初的设计原则依然是相同的,并且目前同时兼容
Vue2
、Vue3
,也并不要求你使用Composition API
Pinia
本质上依然是一个状态管理的库,用于跨组件、页面进行状态共享(这点和Vuex
、Redux
一样)
2. Pinia 和 Vuex 的区别
那么我们不是已经有
Vuex
了吗?为什么还要用Pinia
呢?Pinia
最初是为了探索Vuex
的下一次迭代会是什么样子,结合了Vuex5
核心团队讨论中的许多想法- 最终,团队意识到
Pinia
已经实现了Vuex5
中大部分内容,所以最终决定用Pinia
来替代Vuex
- 与
Vuex
相比,Pinia
提供了一个更简单的API
,具有更少的仪式,提供了Composition-API
风格的API
- 最重要的是,在与
TypeScript
一起使用时具有可靠的类型推断支持
和
Vuex
相比,Pinia
有很多的优势:mutations
不再存在:- 它们经常被认为是非常冗长
- 它们最初带来了
devtools
集成,但这不再是问题
更友好的
TypeScript
支持,Vuex
之前对TS
的支持很不友好不再有
modules
的嵌套结构:- 你可以灵活使用每一个
store
,它们是通过扁平化的方式来相互使用的
- 你可以灵活使用每一个
也不再有命名空间的概念,不需要记住它们的复杂关系
二. 创建 Pinia 的 Store
1. 如何使用 Pinia?
使用
Pinia
之前,我们需要先对其进行安装:bash# npm npm i pinia # yarn yarn add pinia
创建一个
pinia
并且将其传递给应用程序:
2. 认识 Store
- 什么是
Store
?- 一个
Store
(如Pinia
)是一个实体,它会持有为绑定到你组件树的状态和业务逻辑,也就是保存了全局的状态 - 它有点像始终存在,并且每个人都可以读取和写入的组件
- 你可以在你的应用程序中定义任意数量的
Store
来管理你的状态
- 一个
Store
有三个核心概念:state
、getters
、actions
- 等同于组件的
data
、computed
、methods
- 一旦
store
被实例化,你就可以直接在store
上访问state
、getters
和actions
中定义的任何属性
3. 定义一个 Store
定义一个
Store
:- 我们需要知道
Store
是使用defineStore()
定义的 - 并且它需要一个唯一名称,作为第一个参数传递
- 我们需要知道
这个
name
,也称为id
,是必要的,Pinia
使用它来将store
连接到devtools
返回的函数统一使用
useXxx
作为命名方案,这是约定的规范
4. 使用定义的 Store
Store
在它被使用之前是不会创建的,可以通过调用use
函数来使用Store
:注意
Store
获取到后不能被解构,那么会失去响应式:为了从
Store
中提取属性同时保持其响应式,您需要使用storeToRefs()
总结:
store
只有在被使用时,才会被创建store
获取到后不能被解构,否则会失去响应式- 如果想要保持解构的属性的响应式,使用
storeToRefs()
三. Pinia 核心概念 State
1. 认识和定义 State
state
是store
的核心部分,因为store
是用来帮助我们管理状态的在
Pinia
中,状态被定义为返回初始状态的函数jsexport const useCounter = defineStore('counter', { state: () => ({ counter: 0, name: 'later', age: 18 }) })
2. 操作 State
读取和写入
state
:- 默认情况下,可以通过
store
实例访问状态来直接读取和写入状态
- 默认情况下,可以通过
重置
State
:- 可以通过调用
store
上的$reset()
方法将状态重置到其初始值
- 可以通过调用
更改
State
:- 除了直接用
store.counter++
修改store
,还可以调用$patch
方法 - 它允许您使用部分
state
对象同时应用多个更改
- 除了直接用
替换
State
:- 可以通过将其
$state
属性设置为新对象来替换Store
的整个状态 - 从代码角度来说,应该是指向另外一个对象,但从测试结果来看,应该是对
xxx.$state
进行set
操作的时候拦截了,并没有指向一个新的对象,而是替换原对象中同名的属性
- 可以通过将其
四. Pinia 核心概念 Getters
1. 认识和定义 Getters
Getters
相当于Store
的计算属性:它们可以用
defineStore()
中的getters
属性定义getters
中可以定义接受一个state
作为参数的函数
2. 访问 Getters
访问当前
store
的Getters
:Getters
中访问自己的其他Getters
:可以通过
this
来访问到当前store
实例的所有其他属性
访问其他
store
的Getters
:Getters
也可以返回一个函数,这样就可以接受参数:
五. Pinia 核心概念 Actions
1. 认识和定义 Actions
Actions
相当于组件中的methods
- 可以使用
defineStore()
中的actions
属性定义,并且它们非常适合定义业务逻辑
- 可以使用
和
getters
一样,在action
中可以通过this
访问整个store
实例的所有操作
2. Actions 执行异步操作
并且
Actions
中是支持异步操作的,并且我们可以编写异步函数,在函数中使用await