文章目录
一、实现目标 在刷新时,自动获取localStorage的token和user信息
二、所以我们需要设置路由守卫
//前置路由守卫
router.beforeEach((to,from,next) =>{
console.log(1234213)
const storageHandler = new StorageHandler()
//若无token
console.log(storageHandler.getItem(StorageType.Local,'token'))
if (storageHandler.getItem(StorageType.Local,'token') === null ){
//且 to的界面需要权限 则跳转login
if (!to.matched.some(value=>value.meta.requiresAuth))
{
next()
}else{
next({ name:'login'})
}
next()
}
//有token
else {
//但pinia没有user信息,则是因为刷新而导致的用户登录状态消息,需要重新获取,从本地存储便可获取到
const userStore = useUserStore()
console.log(userStore.user)
if (JSON.stringify(userStore.user) === '{}') {
userStore.user = JSON.parse(storageHandler.getItem(StorageType.Local,'user') || "''")
}
}
next()
})
三、但我们发现这样仍然无法进行自动获取,而后我们找到第一次获取user信息的地方
/**
* 方法
* clickBtn 点击登录验证
*/
const clickBtn =async ()=>{
const data = await getUserInfo(accountForm)
// console.log(data.data)
if (data.code == true) {
Message.success('登录成功,即将跳转')
//pinia设置user
userStore.$patch({
user:data.data
})
//token 存入本地
await userStore.saveUserInfo(userStore.user)
storageHandler.setItem(StorageType.Local,'token',userStore.user.token)
router.push('/')
}else{
Message.error('账号或密码错误')
}
}
可以看到user是一个对象 在此处获取到后端发来的数据,而对于对象,我们可以联想到深拷贝、浅拷贝的知识
此时user指向data.data,而在路由守卫上的是:
userStore.user = JSON.parse(storageHandler.getItem(StorageType.Local,'user') || "''")
这是一个赋值语句,会导致user指向新的地址,而在需要user的地方,依然指向的是data.data,所以该语句不会导致proxy改变从而响应到页面渲染
四、解决方法:在原地址上进行修改–浅拷贝,可以使用Object.assign()API
...
//有token
else {
//但pinia没有user信息,则是因为刷新而导致的用户登录状态消息,需要重新获取,从本地存储便可获取到
const userStore = useUserStore()
console.log(userStore.user)
if (JSON.stringify(userStore.user) === '{}') {
// parse第一个参数为string类型 而getItem为string | null 所以当为null的时候我们parse一个''
//不可直接赋值 应该浅拷贝
// userStore.user = JSON.parse(storageHandler.getItem(StorageType.Local,'user') || "''")
userStore.user = Object.assign(userStore.user,JSON.parse(storageHandler.getItem(StorageType.Local,'user') || "''"))
console.log(userStore.user)
}
}
next()