Pinia状态管理
Pinia开始于大概2019年,最初是作为一个实验为Vue重新设计状态管理,让它用起来像组合式API,从那时到现在,最初的设计原则依然是相同的,并且目前同时兼容Vue2、Vue3,也并不要求你使用Composition API
所以说,Pinia本质上依然是一个状态管理的库,用于跨组件、页面进行状态共享(这点和Vuex、Redux一样)
1. Pinia和Vuex的对比
Pinia 最初是为了探索Vuex 的下一次迭代会是什么样子,结合了Vuex 5 核心团队讨论中的许多想法,最终,团队意识到Pinia已经实现了Vuex5中大部分内容,所以最终决定用Pinia来替代Vuex
与Vuex 相比,Pinia 提供了一个更简单的API,具有更少的仪式,提供了Composition-API 风格的API,最重要的是,在与TypeScript 一起使用时具有可靠的类型推断支持
2. 创建Pinia的Store
安装 pinia 的依赖
$ npm install pinia
创建一个pinia并且将其传递给应用程序
创建Pinia的Store
import { createPinia } from "pinia"
const pinia = createPinia()
export default pinia
app.use(pinia)
import { createApp } from 'vue'
import App from './App.vue'
import pinia from "./store"
createApp(App).use(pinia).mount('#app')
3. Store 简介与使用
一个Store (如Pinia)是一个实体,它会持有为绑定到你组件树的状态和业务逻辑,也就是保存了全局的状态,你可以在你的应用程序中定义任意数量的Store来管理你的状态
Store有三个核心概念:state、getters、actions,等同于组件的data、computed、methods
一旦store 被实例化,你就可以直接在store *问state、getters 和actions 中定义的任何属性
定义一个Store
我们需要知道Store 是使用defineStore() 定义的,并且它需要一个唯一名称,作为第一个参数传递,这个name,也称为id,是必要的,Pinia 使用它来将store 连接到devtools
import { defineStore } from "pinia";
export const useUser = defineStore("user", {
state() {
return {
name: 'ximingx'
}
}
})
使用定义的Store
Store在它被使用之前是不会创建的,我们可以通过调用use函数来使用Store
<script setup>
import { useUser } from '../store/user/index'
const userStore = useUser()
console.log(userStore.name); // ximingx
</script>
注意Store获取到后不能被解构,那么会失去响应式,为了从Store 中提取属性同时保持其响应式,您需要使用storeToRefs()
import { storeToRefs } from 'pinia';
import { useUser } from '../store/user/index'
const userStore = useUser()
const {name: name} = storeToRefs(userStore)
name.value = 'qsx'
console.log(name.value);
4. Pinia核心概念State
state 是store 的核心部分,因为store是用来帮助我们管理状态的,在Pinia 中,状态被定义为返回初始状态的函数
import { defineStore } from "pinia";
export const useUser = defineStore("user", {
state() {
return {
isLogin: false,
userInfo: {
nickName: '',
phone: '',
email: '',
lastLoginTime: '',
}
}
}
})
默认情况下,您可以通过store 实例访问状态来直接读取和写入状态
5. Pinia核心概念Getters
Getters相当于Store的计算属性,getters中可以定义接受一个state作为参数的函数
import { defineStore } from "pinia";
export const useUser = defineStore("user", {
state() {
return {
isLogin: false,
userInfo: {
nickName: '',
phone: '',
email: '',
lastLoginTime: '',
}
}
},
getters: {
getUserName: (state) => `用户名: ${state.userInfo.nickName}`
}
})
调用
import {useUser} from '../store/user/index'
const userStore = useUser()
console.log(userStore.getUserName);
Getters中访问自己的其他Getters,我们可以通过this来访问到当前store实例的所有其他属性
6. Pinia核心概念Actions
可以使用defineStore() 中的actions 属性定义,并且它们非常适合定义业务逻辑,和getters一样,在action中可以通过this访问整个store实例的所有操作
并且Actions中是支持异步操作的,并且我们可以编写异步函数,在函数中使用await
import { defineStore } from "pinia";
export const useUser = defineStore("user", {
state() {
return {
isLogin: false,
userInfo: {
nickName: '',
phone: '',
email: '',
lastLoginTime: '',
}
}
},
getters: {
getUserName: (state) => `用户名: ${state.userInfo.nickName}`
},
action: {
async getData() {
}
}
})