Vue中路由守卫的使用

一、token + 全局前置路由守卫

项目中:登录成功以后,服务器会返回token【存储于vuex当中】,如果想获取用户信息 还需要再发请求【用户信息】,携带token给服务器。

问题:为什么刷新页面,用户信息就消失?为什么去别的模块【非home模块】获取用户信息失败?

Vuex存储数据并非是持久化的,所以用户刷新页面,token也就消失了,且没有携带给服务器,所以用户信息也就消失了。

因为你去别的模块根本没有发请求获取用户信息,没办法展示用户信息了

解决:

因为vuex存储数据是非持久化的,所以我们在用户登陆,服务器派发token是,用本地存储将token存储起来

import { setToken, getToken, removeToken } from '@/util/token';
//用户登陆
    async userLogin({ commit }, data) {
        let result = await reqUserLogin(data);
        // console.log(result);
        // token是服务器上传下来的, 是唯一标识
        if (result.code === 200) {
            commit('USERLOGIN', result.data.token);
            //持久化存储token
            setToken(result.data.token);
            //setToken是引入一个专门封装token操作的JS模块
            return 'ok'
        } else {
            return Promise.reject(new Error('Fail'));
        }
    },
const state = {
    token: getToken(), //vuex中数据存储短暂(一刷新页面就没),所以采用本地存储
}
//当退出登陆时,也需要将token清除
const mutations = {
    //清除本地数据
    CLEARINFO(state) {
        //将仓库中token清空
        state.token = "";
        //本地存储数据清空
        removeToken();
    }
}

当我们想去别的模块时,即路径发生变化,而全局前置路由守卫正好可以监测到这一变化,所以我们可以将获取用户信息,携带token的请求放置在其中,这样去别的模块,用户信息就不会消失了。(其中逻辑判断最为复杂、重要)

router.beforeEach(async(to, from, next) => {
    /*
        to:可以获取到你要跳转到哪个路由的信息
        from:可以获取到你从哪个路由来的信息
        next:放行函数
    */
    // 如果有stroe.state.user.token,则说明用户已经登陆
    if (stroe.state.user.token) {
        // 如果用户登陆还想去登陆组件,不准且跳转到首页
        if (to.path == '/login' || to.path == '/register') {
            next('/');
        } else {
            // 去的不是登陆组件,而是其他组件
            // 如果有stroe.state.user.userInfo.name,则说明用户信息已经存在,则放行
            if (stroe.state.user.userInfo.name) {
                next();
            } else {
                // 没有用户信息,则派发action让仓库存储用户信息后在跳转
                try {
                    await stroe.dispatch('userInfo');
                    next()
                } catch (error) {
                    // token失效了,获取不到用户信息,则从新获取
                    // 删除原来的,再重新登陆
                    await stroe.dispatch('userLogout');
                    next('/login');
                }
            }
        }
    } else {
        //未登录:不能去到交易相关、支付相关、个人中心组件
        //如果想去直接跳转到登陆界面,登陆后直接跳转
        if (to.path == '/center/myorder' || to.path == '/pay' || to.path == '/shopcart' || to.path == '/paysuccess') {
            next('/login?redirect=' + to.path);
        } else {
            next()
        }
    }
})

二、其他路由守卫

路由独享守卫:

//beforeEnter 守卫 只在进入路由时触发,不会在 params、query 或 hash 改变时触发
beforeEnter: (to, from, next) => {
            if (from.path == '/trade') {
                next()
            } else {
                next(false);
                /*
                next(false)取消当前的导航。
                    如果浏览器的 URL 改变了(可能是用户手动或者浏览器后退按钮)
                    那么 URL 地址会重置到 from 路由对应的地址
                */
            }
        },

组件内守卫(不常用):

beforeRouteEnter(to, from[,next]) {
    // 在渲染该组件的对应路由被验证前调用
    // 不能获取组件实例 `this` !
    // 因为当守卫执行时,组件实例还没被创建!
  },
  beforeRouteUpdate(to, from[,next]) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 `/users/:id`,在 `/users/1` 和 `/users/2` 之间跳转的时候,
    // 由于会渲染同样的 `UserDetails` 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 因为在这种情况发生的时候,组件已经挂载好了,导航守卫可以访问组件实例 `this`
  },
  beforeRouteLeave(to, from[,next]) {
    // 在导航离开渲染该组件的对应路由时调用
    // 与 `beforeRouteUpdate` 一样,它可以访问组件实例 `this`
  },
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三年ing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值