pinia是一个基于vue 3的状态管理库,它旨在提供更简单、更灵活的状态管理解决方案。与vuex不同,pinia不需要使用复杂的配置和模板代码,而是使用类似于vue组件的方式管理状态。它还支持插件和嵌套模块,可以轻松地扩展和组织状态。与其他状态管理库相比,pinia的性能也更加出色,因为它使用vue3的Reactivity API,能够更好地利用现代浏览器的性能优势。
目录
一、在项目中安装pinia
npm install pinia
二、导入pinia
我们要想使用,在安装后一定是要在main.js中先导入的
// main.js
import { createApp } from 'vue'
import { createPinia } from 'pinia' // 从pinia中导入createPinia方法
import App from './App.vue'
const app = createApp(App)
app.use(createPinia()) // 使用vue实例的use方法,告诉vue我们要使用pinia
app.mount('#app')
三、创建pinia配置状态管理文件
一般来说,我们使用pinia,会在src根目录下创建一个名为store的文件夹来存放配置状态管理文件
假设我们处理一个用户的信息,在store文件夹下新建一个js文件,例如profileStore.js
// profileStore.js
import { defineStore } from "pinia"; // 从pinia中导入,defineStore方法,用于定义一个新的store
import { loginApi } from "../api/login"; // 引入模拟的后台接口,下文有loginApi
export const useProfileStore = defineStore("profile", {
// 使用defineStore方法定义store,'profile'是id,必须有且唯一
state() {
// state表示这个store里的状态,也就是存放数据的地方,类似data
return {
userName: "天凉", // 这里我们定义了一个数据叫userName,用于存放我们的用户名
phone: 18888888888,
avatar: "",
};
},
actions: {
// 类似methods,用于修改state中的值,在pinia的actions中既可以处理同步修改,也可以处理异步
updatePhone(newPhone) {
this.phone = newPhone; //修改号码
}, //这是同步修改
login(userName, password) {
//这是异步修改
// 新增
loginApi(userName, password) // 异步修改,模拟请求后台接口
.then((res) => {
// 登录成功以后,修改了用户名
console.log(res);
// this.userName = res.userName 单个赋值
this.$patch({
// 多个赋值
userName: res.userName,
phone: res.phone,
});
})
.catch((err) => {
console.log(err);
});
},
},
getters: {
// 类似computed 对state的值进行处理
phoneHidden(state) {
return state.phone
.toString()
.replace(/^(\d{3})\d{4}(\d{4})$/, "$1****$2");
}, //把用户的手机号中间四位变成星号
phoneHiddenPlus() {
return (prefix) => prefix + this.phoneHidden;
},
},
});
pinia的store文件中有三个对象,其中state用于存放数据;actions用于修改state中的值,类似vue2中的methods,它既可以处理同步修改,也可以处理异步修改;getters用于对state中的值进行处理,类似vue2中的computed。
模拟的api接口,login.js
// login.js
export function loginApi(userName, password) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if ((userName === "天凉") & (password === "9527")) {
resolve({
userName: "Aserlt",
phone: 17777777777,
});
} else {
reject("用户名或密码错误");
}
}, 1000);
});
}
四、使用
我们在一个vue文件中使用它
<template>
<div @click="click1">
<div>{{ profileStore.userName }}</div>
<div>{{ profileStore.phone }}</div>
<div>{{ profileStore.phoneHidden }}</div>
<div>{{ profileStore.phoneHiddenPlus("+86 ") }}</div>
</div>
</template>
<script setup>
import { onMounted } from "vue";
import { useProfileStore } from "../../store/counter"; //引入我们写好的js文件
const profileStore = useProfileStore();
function click1() {
console.log(1);
// profileStore.updatePhone(19999999999); // 同步修改电话号码
profileStore.login("天凉", "9527"); //异步修改数据
}
</script>
五、跨模块的store互相调用
pinia的跨模块的store互相调用非常简单,我们直接直接导入进来使用就可以了,我们新建一个权限模块的store,文件名为permissionStore.js
// permissionStore.js
import { defineStore } from "pinia";
import { useProfileStore } from "./profileStore"; // 导入其他的store
export const usePermissionStore = defineStore("permission", {
state() {
return {
list: ["add", "delete", "update", "query"], // 权限列表
};
},
getters: {
permissionList(state) {
const profileStore = useProfileStore();
if (profileStore.userName === "天凉") {
// 如果用户名是‘天凉’,那么有所有权限
return state.list;
} else {
return "null";
}
},
},
});
在我们的vue文件中使用
<template>
<div @click="click1">
<div>{{ profileStore.userName }}</div>
<div>{{ profileStore.phone }}</div>
<div>{{ profileStore.phoneHidden }}</div>
<div>{{ profileStore.phoneHiddenPlus("+86 ") }}</div>
<div>权限列表是: {{ permissionStore.permissionList }}</div> //新加入的代码
</div>
</template>
<script setup>
import { onMounted } from "vue";
import { useProfileStore } from "../../store/profileStore";
import { usePermissionStore } from "../../store/permissionStore"; //新加入的代码
const profileStore = useProfileStore();
const permissionStore = usePermissionStore(); //新加入的代码
function click1() {
console.log(1);
// profileStore.updatePhone(19999999999);
profileStore.login("天凉", "9527");
}
</script>