这是我参与「第四届青训营 」笔记创作活动的第7天。
昨天讲了一下 pinia 的使用,在很多时候需要我们去做一下持久化存储(比如以今天做的token存储为例,这里指的是存到 localStorage),当然可以使用localStorage.getItem("xxx")来做,不过这里使用pinia-plugin-persist这款插件就可以更加方便来做这个事情。
01 使用 pinia-plugin-persist
一、安装插件
npm i pinia-plugin-persist --save
二、store/index.js
import { createPinia } from 'pinia'
import piniaPluginPersist from 'pinia-plugin-persist'
const store = createPinia()
store.use(piniaPluginPersist)
export default store
三、store/user.js
export const useUserStore = defineStore({
id: 'user',
state: () => {
return {
name: '张三'
}
},
// 开启数据缓存
persist: {
enabled: true
}
})
四、自定义 key
数据默认存在 sessionStorage 里,并且会以 store 的 id 作为 key。
通过 key & storage 配置就可以指定 key 和存储的位置。
persist: {
enabled: true,
strategies: [
{
key: 'my_user',
storage: localStorage,
}
]
}
五、持久化局部 state
默认所有 state 都会进行缓存,其实能够通过 paths 指定要持久化的字段,其余的则不会进行持久化。
state: () => {
return {
name: '张三',
age: 18,
gender: '男'
}
},
persist: {
enabled: true,
strategies: [
{
storage: localStorage,
paths: ['name', 'age']
}
]
}
所以这里的 gender 将不会存储到 localStorage 。
02 踩坑【大意了】
看到这里相信已经会使用 pinia-plugin-persist 插件了。
但是今天我也是按照这个步骤一步步来,但是没有在 localStorage 看到。
下面是我的代码:
main.ts
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import "./assets/main.css";
const app = createApp(App);
app.use(router);
app.mount("#app");
stores文件夹下的
index.ts
import { createPinia } from "pinia";
import piniaPluginPersist from "pinia-plugin-persist";
const store = createPinia();
store.use(piniaPluginPersist);
export default store;
user.ts
import { defineStore } from "pinia";
export const useUserStore = defineStore({
id: "user",
state: () => {
return {
token: "",
};
},
actions: {
setToken(token: any) {
this.token = token;
},
},
// 开启数据缓存
persist: {
enabled: true,
strategies: [
{
storage: localStorage,
paths: ["token"],
},
],
},
});
login.vue
<template>
......
</template>
<script setup lang="ts">
......
// store
import { useUserStore } from "../stores/user";
const userStore = useUserStore();
......
//账号密码点击登录
const userBtnL = (formEl: any) => {
if (!formEl) return;
formEl.validate((valid: unknown, fields: unknown) => {
if (valid) {
login({
username: ruleForm.username,
password: Encrypt(ruleForm.userpwd),
}).then((res: any) => {
if (res.code != 1000) {
ElMessage({message: res.message,type: "error",});
return;
}
ElMessage({message: `${ruleForm.username}登陆成功!`,type: "success",});
// 将 token 存到 userStore 里面
userStore.setToken(res.data.access_token);
});
} else {
console.log("error submit!", fields, valid);
}
});
};
</script>
<style scoped>......</style>
咋一看没什么问题。
而且我发现在 vue devtool 可以看到确实已经存到 token 里面了,但是没有在 localStorage 看到。
这个问题我卡住了很久,最终找到了原因。
原来是为了方便对其进行了分包,在 index.ts 文件 use pinia-plugin-persist 等插件,在 user.ts 就是关于用户的,在 post.ts 就是关于文章的 ...... 但是我忘记了一个最重要的,就是在main.ts 引入 stores 下的 index.ts 的 createPinia() !所以只要修改一下 main.ts 如下:
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
// !!!不要忘记引入
import store from "./stores";
import "./assets/main.css";
const app = createApp(App);
app.use(router);
app.use(store);
app.mount("#app");
最后问题解决,主要是这种不报错的bug最难找了,所以打代码还是要细心一点!