admin管理员组文章数量:1635670
我们需要通过路由来进行一些操作,比如最常见的登录权限验证,当用户满足条件时,才让其进入导航,否则就取消跳转,并跳到登录页面让其登录。
全局守卫
vue-router全局有三个守卫:
- router.beforeEach 全局前置守卫 进入路由之前
- router.beforeResolve 全局解析守卫,在beforeRouteEnter调用之后调用
- router.afterEach 全局后置钩子 进入路由之后
使用方法:
// main.js 入口文件
import router from './router'; // 引入路由
router.beforeEach((to, from, next) => {
next();
});
router.beforeResolve((to, from, next) => {
next();
});
router.afterEach((to, from) => {
console.log('afterEach 全局后置钩子');
});
to,from,next 这三个参数:
to和from是将要进入和将要离开的路由对象,路由对象指的是平时通过this.$route获取到的路由信息配置对象,比如path传参 this.$route.query接收。
next:Function 这个参数是个函数,且必须调用,否则不能进入路由(页面空白)。
-
next() 进入该路由。
-
next(false): 取消进入路由,url地址重置为from路由地址(也就是将要离开的路由地址)。
-
next 跳转新路由,当前的导航被中断,重新开始一个新的导航。
我们可以这样跳转:next('path地址')或者next({path:''})或者next({name:''}) 且允许设置诸如 replace: true、name: 'home' 之类的选项 以及你用在router-link或router.push的对象选项。
路由独享守卫
如果你不想全局配置守卫的话,你可以为某些路由单独配置守卫,写在路由配置里
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// 参数都一样
}
}
]
})
路由组件内的守卫:
- beforeRouteEnter 进入路由前
- beforeRouteUpdate 路由复用同一个组件时
- beforeRouteLeave 离开当前路由时
三个钩子函数
beforeRouteEnter (to, from, next) {
// 在路由独享守卫后调用 不能获取组件实例 this,组件实例还没被创建
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用 可以访问组件实例 this
// 可以用来接收动态路由传过来的参数
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
},
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用,可以访问组件实例 this
}
beforeRouteEnter访问this
因为钩子在组件实例还没被创建的时候调用,所以不能获取组件实例 this
,可以通过传一个回调给next
来访问组件实例 。
但是回调的执行时机在mounted后面,所以在我看来这里对this的访问意义不太大,可以放在created
或者mounted
里面。
beforeRouteEnter (to, from, next) {
console.log('在路由独享守卫后调用');
next(vm => {
// 通过 vm 访问组件实例 this 执行回调的时机在mounted后面,
})
}
beforeRouteLeave:
导航离开该组件的对应路由时调用,我们用它来禁止用户离开,比如还未保存草稿,或者在用户离开前,将setInterval
销毁,防止离开之后,定时器还在调用。
beforeRouteLeave (to, from , next) {
if (文章保存) {
next(); // 允许离开或者可以跳到别的路由 上面讲过了
} else {
next(false); // 取消离开
}
}
关于钩子的一些知识:
路由钩子函数的错误捕获
如果我们在全局守卫/路由独享守卫/组件路由守卫的钩子函数中有错误,可以这样捕获:
router.onError(callback => {
// 2.4.0新增 并不常用,了解一下就可以了
console.log(callback, 'callback');
});
跳转死循环解决
{
path: '/login',
name: 'login',
component: () => import('../views/login.vue'),
meta: {
intercept: true
}
}
router.beforeEach((to, from, next) => {
let token = localStorage.getItem('token')
console.log(to.meta.intercept);
if (token && token != null) { // 本地有 token 去下一步
next()
} else { // 不是 login 页面我再去跳 ,是 login 就会死循环,因为login 也是页面就会被守卫
if (to.meta.intercept && to.path != '/login') {
// 路由原信息为true 并且 不是 login 页面 去login 防止死循环
next('/login')
} else {
next() // vue3 从 next 换成了 return 执行下一步
}
}
})
全局后置钩子的跳转:
文档中提到因为router.afterEach不接受next
函数所以也不会改变导航本身,意思就是只能当成一个钩子来使用,但是我自己在试的时候发现,我们可以通过这种形式来实现跳转:
// main.js 入口文件
import router from './router'; // 引入路由
router.afterEach((to, from) => {
if (未登录 && to.path !== 'login') {
router.push({ path: 'login' }); // 跳转login
}
});
s-z-h
版权声明:本文标题:vue2的路由守卫(钩子函数),路由死循环怎么解决? 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/dongtai/1729176572a1188795.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论