目录
- 1_Pinia和Vuex的对比
- 1.1_介绍pinia
- 1.2_Pinia和Vuex的区别
- 2_创建Pinia的Store
- 2.1_安装使用
- 2.2_Store
- 2.3_定义一个Store
- 3_Pinia核心概念State
- 3.1_认识和定义State
- 3.2_操作State
- 4_Pinia核心概念Getters
- 4.1_认识
- 2.2_访问Getters
- 5_Pinia核心概念Actions
- 5.1_认识
- 5.2_Actions执行异步操作
1_Pinia和Vuex的对比
1.1_介绍pinia
Pinia(发音为/piːnjʌ/,如英语中的“peenya”)是最接近piña(西班牙语中的菠萝)的词;
- Pinia开始于大概2019年,最初是作为一个实验为Vue重新设计状态管理,让它用起来像组合式API(Composition API)。
- 从那时到现在,最初的设计原则依然是相同的,并且目前同时兼容Vue2、Vue3,也并不要求使用Composition API;
- Pinia本质上依然是一个状态管理的库,用于跨组件、页面进行状态共享(这点和Vuex、Redux一样);
访问官网
1.2_Pinia和Vuex的区别
有Vuex,为什么还要用Pinia?
- Pinia 最初是为了探索 Vuex 的下一次迭代会是什么样子,结合了 Vuex 5 核心团队讨论中的许多想法;
- 最终,团队意识到Pinia已经实现了Vuex5中大部分内容,所以最终决定用Pinia来替代Vuex;
- 与 Vuex 相比,Pinia 提供了一个更简单的 API,具有更少的仪式,提供了 Composition-API 风格的 API;
- 最重要的是,在与 TypeScript 一起使用时具有可靠的类型推断支持;
和Vuex相比,Pinia有很多的优势:
- 比如mutations消失,减少冗长的步骤
- 更友好的TypeScript支持,Vuex之前对TS的支持很不友好;
- 不再有modules的嵌套结构,可以灵活使用每一个store,它们是通过扁平化的方式来相互使用的;
- 也不再有命名空间的概念,不需要记住它们的复杂关系;
2_创建Pinia的Store
2.1_安装使用
执行安装命令,二选一
yarn add pinia
npm install pinia
在src/store/路径下,或者src/pinia/路径下,创建index.js文件,写入下方的代码,然后就成功创建一个pinia并可导出使用
import { createPinia } from 'pinia'
const pinia = createPinia()
export default pinia
2.2_Store
什么是Store?
- 一个 Store (如 Pinia)是一个实体,它会持有为绑定到组件树的状态和业务逻辑,也就是保存了全局的状态;
- 比较像始终存在,并且每个人都可以读取和写入的组件;
- 可以在应用程序中定义任意数量的Store来管理的状态;
Store有三个核心概念:
- state、getters、actions;
- 等同于组件的data、computed、methods;
- 一旦 store 被实例化,就可以直接在 store 上访问 state、getters 和 actions 中定义的任何属性;
2.3_定义一个Store
Store在它被使用之前是不会创建的,可以通过调用use函数来使用Store。
比如下面,counter.js是已经定义好的一个状态管理文件
<template>
<div class="home">
<h2>Home View</h2>
<h2>count: {{ counterStore.count }}</h2>
<h2>count: {{ count }}</h2>
<button @click="incrementCount">count+1</button>
</div>
</template>
<script setup>
import { storeToRefs } from 'pinia'
import useCounter from '@/stores/counter';
const counterStore = useCounter()
const { count } = storeToRefs(counterStore)
function incrementCount() {
counterStore.count++
}
</script>
注意Store获取到后不能被解构,那会失去响应式,为了从 Store 中提取属性同时保持其响应式,需要使用storeToRefs()
3_Pinia核心概念State
3.1_认识和定义State
state 是 store 的核心部分,因为store是用来帮助管理状态的。 在 Pinia 中,状态被定义为返回初始状态的函数;
比如下面/src/store/user.js的代码
import { defineStore } from 'pinia'
const useUser = defineStore("user", {
state: () => ({
name: "coder",
age: 18,
level: 100
})
})
export default useUser
3.2_操作State
读取和写入 state, 默认情况下,可以通过 store 实例访问状态来直接读取和写入状态;
import useUser from '@/stores/user';
const userStore = useUser()
userStore.age++
userStore.name = "xixi"
重置 State,可以通过调用 store 上的 $reset() 方法将状态 重置 到其初始值;
const userStore = useUser()
userStore.$reset()
改变State
- 除了直接用 store.age++ 修改 store,还可以调用
$patch
方法; - 它允许使用部分“state”对象同时应用多个更改;
const userStore = useUser()
userStore.$patch({
name: "hhh",
age: 25,
leval: 50
})
替换State, 可以通过将其 $state
属性设置为新对象来替换 Store 的整个状态:
userStore.$state({
name: "hehe",
age: 10,
leval: 2
})
4_Pinia核心概念Getters
4.1_认识
Getters相当于Store的计算属性computed:
- 它们可以用 defineStore() 中的 getters 属性定义;
- getters中可以定义接受一个state作为参数的函数;
比如src/store/counter.js
// 定义关于counter的store
import { defineStore } from 'pinia'
import useUser from './user'
const useCounter = defineStore("counter", {
state: () => ({
count: 99,
friends: [
{ id: 111, name: "xixi" },
{ id: 112, name: "kobe" },
{ id: 113, name: "james" },
]
}),
getters: {
// 基本使用
doubleCount(state) {
return state.count * 2
}
})
export default useCounter
2.2_访问Getters
访问当前store的Getters
const conterStore = useCouter()
console.log(counterStore.doubleCount)
console.log(counterStore.doubleCountAddOne)
Getters中访问自己的其他Getters, 可以通过this来访问到当前store实例的所有其他属性;
getters: {
// 1.基本使用
doubleCount(state) {
return state.count * 2
},
// 2.一个getter引入另外一个getter
doubleCountAddOne() {
// this是store实例
return this.doubleCount + 1
},
}
访问其他store的Getters
getters: {
// getters中用到其他的store中的数据
showMessage(state) {
// 1.获取user信息
const userStore = useUser()
// 2.获取自己的信息
// 3.拼接信息
return `name:${userStore.name}-count:${state.count}`
}
}
Getters也可以返回一个函数,这样就可以接受参数
getters: {
// getters也支持返回一个函数
getFriendById(state) {
return function(id) {
for (let i = 0; i < state.friends.length; i++) {
const friend = state.friends[i]
if (friend.id === id) {
return friend
}
}
}
}
}
5_Pinia核心概念Actions
5.1_认识
Actions 相当于组件中的 methods,可以使用 defineStore() 中的 actions 属性定义,并且它们非常适合定义业务逻辑;
和getters一样,在action中可以通过this
访问整个store实例的所有操作;
actions: {
increment() {
this.count++
},
incrementNum(num) {
this.count += num
}
}
5.2_Actions执行异步操作
Actions中是支持异步操作的,且可以编写异步函数,在函数中使用await;
在action中可以通过`this`访问整个store实例的所有操作;
actions: {
increment() {
this.count++
},
incrementNum(num) {
this.count += num
}
}