在项目中,一般会遇到一些页面需要登录后才可访问,比如电商项目中的个人中心和支付等等页面,不登陆时用户应该是访问不了的。 所以需要在路由跳转前进行判断——导航守卫-全局前置守卫。
const router = createRouter({
history: createWebHistory(),
routes,
scrollBehavior(to, from, savedPosition) {
// 始终滚动到顶部
return { top: 0 }
},
})
// 全局守卫 : 全局前置守卫(在路由跳转之前进行判断)
router.beforeEach(async (to,from)=>{
// to: 即将要进入的目标
// from: 当前导航正要离开的路由
// 用户登录了才会有token,所以可以用来判断是否登录
let token = store.state.user.token;
// 这里用于后续判断用户信息,不是判断的userInfo,因为userInfo是对象,即使是空对象,if判断中也会认为是true。所以判断对象里面的字符串即可
let name = store.state.user.userInfo.name;
// 用户已经登陆
if(token){
// 用户已登陆,但访问login,不跳转,重定向到home
if(to.path == '/login'||to.path=='/register'){
return {path:'/home'};
}else{//用户登录,访问其他页面【home|search等等】,需要判断是否有用户信息
if(!name){
// 没有用户信息,仓库派发action让仓库存储用户信息
try {
await store.dispatch("getUserInfo");
} catch (error) {
// token失效获取不到用户信息, 清除token,返回登陆页
await store.dispatch("userLogout");
return {path:'/login'};
}
}
}
}else{ //未登录
// 未登录,不能去交易相关、支付相关【pay|paysuccess】、个人中心[center/myorder|| center/grouporder]的页面
// 若未登录,访问了上述页面,应跳转至登陆页
if(to.path.indexOf('/trade')!=-1 || to.path.indexOf('/pay')!=-1 || to.path.indexOf('/center')!=-1){
return {path:'/login',query:{redirect:'/center/myorder'}};
}
}
})
export default router;
主要想记录的就是未登录时如果访问支付页面,应先跳转到登陆页,然后登陆后应该自动再跳回支付页面,而不是一味的跳到home页。
vue2中可以用next()里面字符串拼接query参数。 vue3的话,我是用上面的这种写法,重定向了一下。
然后登陆组件的路由跳转就要做出相应判断了。
// 登陆
async function userLogin() {
try {
const { phone, password } = LoginInfo;
if (phone && password) {
await store.dispatch("userLogin", { phone, password });
}
// 登陆成功,跳转到home
// 看路由中是否包含query参数,如果有,调到query参数指定路由,若没有,跳转到home
let toPath = $route.query.redirect || "/home";
// $router.push("/home");
$router.push(toPath);
} catch (error) {
alert(error.message);
}
}
如果路由中有query参数,就跳转相应路由,没有的话,代表就是单纯的要登陆,登陆后跳转到home