Pinia状态管理
最初是作为一个实验为 Vue重新设计状态管理,让它用起来像组合式API
Pinia和Vuex的对比
- 为什么要用 Pinia
- Pinia 最初是为了 探索Vuex的下一次迭代 会是什么样子,结合了 Vuex5核心团队讨论中的很多想法
- 最终,团队意识到 Pinia已经实现了Vuex5中大部分的内容 ,所以最终决定 使用Pinia来代替Vuex
- 与Vuex相比,Pinia提供了一个更加简单的API,具有更少的仪式 ,提供了 Composition-API风格的API
- 最重要的是,能够更好的支持TypeScript
- 与Vuex相比,Pinia的优势
- 比如mutations不再存在
- 更友好的支持TypeScript
- 不再有modules
- 不再有命名空间的概念,不需要记住复杂的关系
如何使用Pinia
- 首先通过
npm install pinia
安装pinia - 安装完成后,在src文件夹下面创建store文件夹
- 创建index.js的入口文件
js
import { createPinia } from "pinia";
export default createPinia();
- 在main.js使用pinia插件
js
import { createApp } from "vue";
import App from "./App.vue";
import pinia from "./store";
const app = createApp(App);
app.use(pinia);
app.mount("#app");
- 在store文件夹下面创建不同的store
- 创建一个counter.js的store文件,用于保存计数的状态
js
import { defineStore } from "pinia";
//defineStore创建store,可以创建多个store
//第一个参数是用于命名store的
//第二个参数是store的具体内容
const useCounter = defineStore("counter", {
state: () => ({
count: 199,
}),
});
//返回值是一个函数,将函数暴露出去
export default useCounter;
- 而后在具体的组件中引入暴露的函数,完成调用即可
html
<template>
<!-- 直接访问store中的变量即可 -->
{{ counterStore.count }}
</template>
<script setup>
//引入暴露的store函数
import useCounter from "./store/counter.js";
const counterStore = useCounter();
</script>
<style scoped></style>
认识Store
- 什么是Store
- 一个store(如pinia)是一个实体(通过defineStore()创建 ),它会持有组件树种的 状态和业务逻辑(业务逻辑主要是网络请求等内容),也就是保存了全局的状态
- 有点像始终存在,并且 每个人都可以读取和写入的组件
- 可以在项目种,定义 任意数量的Store来管理状态
- Stroe有三个核心概念
- state、getters、actions
- 等同于组件的 data、computed、methods
- 一旦 store被实例化,可以直接在store上访问 state、getters、actions种定义的任何属性
定义一个store
在上面的例子中有讲过store的定义
- 使用 defineStore 进行定义
- 第一个参数:是store的唯一名称,也成为id,是必要的
- 第二个参数是具体的store对象
- 返回的函数同一使用useX进行命名
js
import { defineStore } from "pinia";
//defineStore创建store,可以创建多个store
//第一个参数是用于命名store的
//第二个参数是store的具体内容
const useCounter = defineStore("counter", {
state: () => ({
count: 199,
}),
});
//返回值是一个函数,将函数暴露出去
export default useCounter;
认识和定义State
- state是store的核心部分
js
import { defineStore } from "pinia";
//defineStore创建store,可以创建多个store
//第一个参数是用于命名store的
//第二个参数是store的具体内容
const useCounter = defineStore("counter", {
state: () => ({
count: 199,
}),
});
//返回值是一个函数,将函数暴露出去
export default useCounter;
操作State
- 读取和写入state:
- 默认情况下,可以通过store实例访问状态来直接读取和写入状态
js
//引入暴露的store函数
import useCounter from "./store/counter.js";
const counterStore = useCounter();
//读取
counterStore.count
//修改
counterStore.count++
- 重置State
- 可以通过调用store上的**$reset()**方法讲状态重置到初始值
js
//引入暴露的store函数
import useCounter from "./store/counter.js";
const counterStore = useCounter();
counterStore.$reset()//会将counter恢复到初始定义的状态
- 一次性修改多个State
- 通过 $patch
js
//引入暴露的store函数
import useCounter from "./store/counter.js";
const counterStore = useCounter();
counterStore.$patch({
name:"zhangcheng",
age:"18"
})
- 替换state
- 通过 $state方法进行替换
js
//引入暴露的store函数
import useCounter from "./store/counter.js";
const counterStore = useCounter();
counterStore.$state = {
name:"zhangcheng",
age:"18"
}
认识和定义Getters
- 基本使用,获取本store实例下的state
js
import { defineStore } from "pinia";
const useCounter = defineStore("counter", {
state: () => ({
count: 199,
}),
getters:{
doubleCount(state){
//通过传参的方式进行访问
return state.count
},
doubleCountAddOne(){
//可以通过this进行访问
return this.count*2+1
}
}
});
//返回值是一个函数,将函数暴露出去
export default useCounter;
//使用方法同state,先引入暴露的函数,执行,通过.的方式进行访问
- 使用getters中的数据
- 可以通过 this直接访问
js
import { defineStore } from "pinia";
const useCounter = defineStore("counter", {
state: () => ({
count: 199,
}),
getters:{
doubleCount(state){
//通过传参的方式进行访问
return state.count
},
doubleCountAddOne(){
//可以通过this访问getters中的变量
return this.doubleCount+1
}
}
});
//返回值是一个函数,将函数暴露出去
export default useCounter;
- 用到别的store中的数据
js
import { defineStore } from "pinia";
//引入其他的store
import userInfo from "./store/user.js";
const useCounter = defineStore("counter", {
state: () => ({
count: 199,
}),
getters:{
getMessage(){
//实例化而后使用
const userStore = userInfo()
return userInfo.name + count
}
}
});
//返回值是一个函数,将函数暴露出去
export default useCounter;
认识和定义Actions
- Actions相当于组件中的methods
- 与getters一样,可以通过this访问store中的变量,但是没有传入state参数
js
import { defineStore } from "pinia";
//引入其他的store
import userInfo from "./store/user.js";
const useCounter = defineStore("counter", {
state: () => ({
count: 199,
}),
actions:{
countAdd(num){
//可以传入参数
//直接通过this进行访问state中的状态
this.count += num
}
}
});
//具体使用
//引入暴露的store函数
import useCounter from "./store/counter.js";
const counterStore = useCounter();
//直接调用方法即可
counterStore.countAdd(10)
执行异步操作
js
import { defineStore } from "pinia";
//引入其他的store
import userInfo from "./store/user.js";
const useCounter = defineStore("counter", {
actions:{
async getData(){
const res = await fetch(xxxx)
const data = await res.json()
//改变state状态
this.list = data
//返回data
retrun data
}
}
});