一、特点
-
完整的 ts 支持
-
三大核心:state(存储的值),getters(计算属性),actions也可支持同步(改变值的方法,支持同步和异步)
-
与vuex相比,去除了mutations(actions也可支持同步)和modules(只有store之间的互相引用)
二、安装
yarn add pinia
三、使用
1. 创建 pinia 实例
新建 store/index.ts(项目根目录下新建store文件夹,并创建index.ts文件)
import { createPinia } from 'pinia';
const store = createPinia();
export default store;
复制代码
2. 在 main.js 中引用
import { createApp } from 'vue';
import App from './App.vue';
import store from './store';
const app = createApp(App);
app.use(store);
app.mount('#app');
复制代码
3. 创建 store
新建store/user.ts
import { defineStore } from 'pinia';
// defineStore 第一个参数是id,必需且值唯一
export const useUserStore = defineStore('user', {
//state返回一个函数,防止作用域污染
state: () => {
return {
userInfo: {
name: 'zhangsan',
age: 23,
},
token: 'S1',
};
},
getters: {
newName: (state) => state.userInfo.name + 'vip',
},
actions: {
//更新整个对象
updateUserInfo(userInfo: { name: string; age: number }) {
this.userInfo = userInfo;
},
//更新对象中某个属性
updateAge(age: number) {
this.userInfo.age = age;
},
//更新基础数据类型
updateToken(token: string) {
this.token = token;
},
},
});
复制代码
4. 使用 store
store 是一个用 reactive 包装的对象,直接解构读取state会失去响应式,因此需要storeToRefs,它将为每一个响应式属性创建引用;需通过 .value 读取解构出来的值
<template>
<div> <div>姓名:{{ userInfo.name }} 年龄:{{ userInfo.age }}</div> <div>token:{{ token }}</div> <div>getter值:{{ newName }}</div> <button @click="handleUser">更新用户</button> <button @click="handleAge">更新年龄</button> <button @click="handleToken">更新token</button> </div>
</template>
<script setup lang="ts"> import { storeToRefs } from 'pinia'; import { useUserStore } from '@/store/user'; //路径别名,引入store const userStore = useUserStore(); //storeToRefs 会跳过所有的 action 属性 const { userInfo, token, newName } = storeToRefs(userStore); //action 属性直接解构 const { updateUserInfo, updateAge, updateToken } = userStore; const handleUser = () => { updateUserInfo({ name: 'lisi', age: 24 }); }; const handleAge = () => { //userInfo是一个ref响应式引用,需通过.value取值 updateAge(userInfo.value.age + 1); }; const handleToken = () => { updateToken('23234'); }; </script>
复制代码
5. 异步 actions
除了上面展示的同步action,action也可以是异步的
新建store/list.ts
import { defineStore } from 'pinia';
const getData = () => {
return new Promise<number>((resolve) => {
setTimeout(() => {
resolve(Math.random() * 100);
}, 200);
});
};
export const useListStore = defineStore('list', {
state: () => {
return {
list: [] as number[],
};
},
actions: {
async updateList() {
try {
const data = await getData();
this.list.push(data);
} catch {
/* empty */
}
},
},
});
复制代码
6. store 的相互引用
每个store可看做一个hook。相互引用即调用不同hook
新建store/userSex.ts
import { defineStore } from 'pinia';
import { useUserStore } from './user';
enum Sex {
man = '男人',
woman = '女人',
}
export const userSexStore = defineStore('user2', {
state: () => {
return {
sex: Sex.man,
};
},
actions: {
updateSex() {
const userStore = useUserStore(); // 引用其他store
if (userStore.userInfo.name !== 'zhangsan') this.sex = Sex.woman;
},
},
});
复制代码
7. 路由钩子中使用store
使用store的前提是保证pinia已被注册
import { useUserStore } from '@/store/user';
router.beforeEach((to, from, next) => {
// ✅ 这样做是可行的,因为路由器是在其被安装之后开始导航的,
// 而此时 Pinia 也已经被安装。
const store = useUserStore();
if (!store.token) {
next({
path: '/login',
});
} else {
next();
}
});
复制代码
四、数据持久化
1. 安装插件
yarn add pinia-plugin-persistedstate
2. 引用插件
修改 store/index.ts
import { createPinia } from 'pinia';
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate';
const store = createPinia();
store.use(piniaPluginPersistedstate); // 使用持久化插件
export default store;
复制代码
3. 在store模块中启用持久化
在user.ts中启用:添加persist配置项
import { defineStore } from 'pinia'
export const useUserStore = defineStore('user', {
state: () => ({
...
}),
getters: { ... },
actions: { ... },
// 开始数据持久化
persist: true,
})
复制代码
当更新state值时,会默认存储到localStorage中
4. 修改key与存储位置
默认存储到localStorage的key值就是store模块id值。可以修改key值和存储位置
//将persist: true,改为
persist: {
key: 'storekey', // 修改存储的键名,默认为当前 Store 的 id
storage: window.sessionStorage, // 存储位置修改为 sessionStorage
},
复制代码
5. 自定义要持久化的字段
默认会将store中的所有字段都缓存,可以通过paths点符号路径数组指定要缓存的字段
persist: {
paths: ['userInfo.name'], //存储userInfo的name
},
复制代码
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




