用户登录成功之后,有几个要点:
要点1:用户在不同路由模块之间切换的时候,有进度条:点击组件时进度条启动,能访问到了以后进度条消失
要点2:不同路由模块之前访问的条件不同:比如用户未登录,只能访问login页面;登录之后,当token过期了,再点击页面别的组件时,只能跳转到登录页面
要点3:登录成功之后,访问所有的路由模块都需要用户信息,比如展示用户头像和名字等
解决方案:
要点1--------> nprogress进度条插件
要点2-------->全局前置守卫判断,放行与否
要点3--------->在全局前置守卫那里发请求,每次切换路由,都要获取用户信息
router.beforeEach(async (to: any, from: any, next: any) => {
//打开网页时的标题 类似“硅谷甄选平台-用户管理”
document.title = `${setting.title} - ${to.meta.title}`
//to:你将要访问那个路由
//from:你从来个路由而来
//next:路由的放行函数
nprogress.start();
//获取token,去判断用户登录、还是未登录
let token = userStore.token;
//获取用户名字
let username = userStore.username;
//用户登录判断
if (token) {
//登录成功,访问login,不能访问,指向首页
if (to.path == '/login') {
next({ path: '/' })
} else {
//登录成功访问其余六个路由(登录排除)
//有用户信息
if (username) {
//放行
next();
} else {
//如果没有用户信息,在守卫这里发请求获取到了用户信息再放行
try {
//获取用户信息
await userStore.userInfo();
//放行
//万一:刷新的时候是异步路由,有可能获取到用户信息、异步路由还没有加载完毕,出现空白的效果
next({...to});
} catch (error) {
//token过期:获取不到用户信息了
//用户手动修改本地存储token
//退出登录->用户相关的数据清空
await userStore.userLogout();
//优化:当用户重新登录的时候,跳到用户上次停留的页面,而不是首页
next({ path: '/login', query: { redirect: to.path } })
}
}
}
} else {
//用户未登录判断
if (to.path == '/login') {
next();
} else {
next({ path: '/login', query: { redirect: to.path } });
}
}
})
//全局后置守卫
router.afterEach((to: any, from: any) => {
nprogress.done();
});
注意:
1、在组件以外的地方(比如ts文件)如果要拿小仓库的数据,要先拿大仓库的数据,不然报错
import useUserStore from './store/modules/user';
import pinia from './store';
let userStore = useUserStore(pinia);
2、next({...to})意思和用法VUE 路由守卫 next() / next({ ...to, replace: true }) / next(‘/‘) 说明_Incimo的博客-CSDN博客