您现在的位置是:首页 >其他 >【Vue工程】006-Pinia网站首页其他
【Vue工程】006-Pinia
简介【Vue工程】006-Pinia
【Vue工程】006-Pinia
文章目录
一、概述
1、官网
https://pinia.vuejs.org/zh/
2、官方 Demo
https://stackblitz.com/github/piniajs/example-vue-3-vite?file=README.md
3、简介
Pinia 是 Vue 的专属状态管理库,它允许你跨组件或页面共享状态。
4、优点
- 使用
pinia
作为数据仓库,可以很方便的在多个组件/页面
中共用同一个变量; - 对
TypeScript
的支持更加友好; - 可以在不重载页面的前提下修改仓库数据,且能实时响应在页面。
二、基本使用
1、安装
pnpm add pinia
2、创建 pinia 实例
创建 src/store/index.ts
import { createPinia } from 'pinia';
const store = createPinia();
export default store;
3、在 main.ts
注册
import { createApp } from 'vue';
import './style.css';
import App from './App.vue';
// 导入路由
import router from './router';
// 导入 store
import store from './store';
const app = createApp(App);
// 注册路由
app.use(router);
// 注册 store
app.use(store);
app.mount('#app');
4、创建 user.ts
创建 src/store/user.ts
import { defineStore } from 'pinia';
// 定义一个 userinfo 类型
export interface User {
name?: string;
age?: number;
token?: string;
}
// defineStore 第一个参数是id,必需且值唯一
export const useUserStore = defineStore('user', {
// state返回一个函数,防止作用域污染
state: () => ({
name: 'zibo',
age: 26,
token: '202305110056',
}),
// getters:获取 state 中的数据
// getters 与 vue 中的 computed 类似,提供计算属性
getters: {
// 获取整个对象
user: (state: User) => state,
// 获取对象中某个属性
newName: (state: User) => state.name + '123',
},
// actions:更新 state 中的数据
actions: {
// 更新整个对象
setUser(user: User) {
this.$patch(user);
},
// 更新对象中某个属性
setName(name: string) {
this.$patch({ name });
},
},
});
5、使用 useUserStore
<template>
<div>姓名:{{ newName }} 年龄:{{ user.age }}</div>
<div>token:{{ user.token }}</div>
<button @click="handleUser">更新用户</button>
<button @click="handleName">更新名字</button>
</template>
<script lang="ts" setup>
// 导入 useUserStore
import { useUserStore } from '@/store/user';
// 引入 storeToRefs 函数,使得解构 store 仍具有响应式特性
import { storeToRefs } from 'pinia';
// 通过 useUserStore 获取到 userStore
const userStore = useUserStore();
// storeToRefs 会跳过所有的 action 属性,只暴露 state 属性
const { user, newName } = storeToRefs(userStore);
// action 属性直接解构
const { setName, setUser } = userStore;
// 更新用户
const handleUser = () => {
setUser({
name: '张三',
age: 18,
token: '123456',
});
};
// 更新名字
const handleName = () => {
setName('李四');
};
</script>
<style scoped></style>
三、异步 actions
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 */
}
},
},
});
四、store 的相互引用
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;
},
},
});
五、路由钩子中使用 store
import { useUserStore } from '@/store/user';
router.beforeEach((to, from, next) => {
// ✅ 这样做是可行的,因为路由器是在其被安装之后开始导航的,
// 而此时 Pinia 也已经被安装。
const store = useUserStore();
if (!store.token) {
next({
path: '/login',
});
} else {
next();
}
});
六、数据持久化
1、安装插件
pnpm add pinia-plugin-persistedstate
2、使用插件
修改 src/store/index.ts
import { createPinia } from 'pinia';
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate';
const store = createPinia();
store.use(piniaPluginPersistedstate); // 使用持久化插件
export default store;
3、在 store 模块中启用持久化
在 src/store/user.ts 中启用:添加 persist 配置项
当更新 state 值时,会默认存储到 localStorage 中
import { defineStore } from 'pinia'
export const useUserStore = defineStore('user', {
state: () => ({
...
}),
getters: { ... },
actions: { ... },
// 开始数据持久化
persist: true,
})
4、修改 key 与存储位置
默认存储到 localStorage 的 key 值就是 store 模块 id 值。可以修改 key 值和存储位置
//将persist: true,改为
persist: {
key: 'storekey', // 修改存储的键名,默认为当前 Store 的 id
storage: window.sessionStorage, // 存储位置修改为 sessionStorage
},
5、自定义要持久化的字段
默认会将 store 中的所有字段都缓存,可以通过 paths 点符号路径数组指定要缓存的字段
persist: {
paths: ['user.name'], // 存储 user 对象的 name 属性
},
七、补充:修改 state 的几种方法
1、直接修改
const add = () => store.counter ++
2、$patch 传递参数
const add = () => {
store.$patch({
count:store.counter + 2,
})
};
3、$patch 传递方法
const add = () => {
store.$patch(state => {
state.counter += 10
})
};
4、actons
// actions:更新 state 中的数据
actions: {
// 更新整个对象
setUser(user: User) {
this.$patch(user);
},
// 更新对象中某个属性
setName(name: string) {
this.name = name;
},
},
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。