与登录有关的路由鉴权

用户登录成功之后,有几个要点:

要点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博客

你可能感兴趣的:(vue网上项目,前端,vue.js)