导航守卫
vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航(路由发生改变才会守卫)。
参数 params 或查询 query 的改变并不会触发进入/离开的导航守卫。你可以通过观察 $route
对象来应对这些变化,或使用 beforeRouteUpdate
的组件守卫。
const User = {
template: '...',
watch: {
'$route' (to, from) {
// 对路由变化作出响应...
}
}
}
const User = {
template: '...',
beforeRouteUpdate (to, from, next) {
// react to route changes...
// don't forget to call next()
}
}
1.全局守卫(router.beforeEach)
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
//`to: Route`: 即将要进入的目标 路由对象{path,params,query}
//`from: Route`: 当前导航正要离开的路由
//`next: Function`: 一定要调用该方法来 **resolve** 这个钩子。执行效果依赖 `next` 方法的调用参数。
//可以通过判断跳转的路径参数,用next判断是否要跳转到这个路由,或者跳转到一个新路由
}
要确保执行next函数,否则会卡在这里
配合meta可以 可用于判断跳转需不需要用户登录
router=new VueRouter(function(){
routes:[
{path:'/',component:'Home'},
{path:'/',component:' Publish',meta:{needLogin:true}},//代表进入该路由需要登录
{path:'/login',component:Login}
]
})
router.beforeEach((to, from, next){
if(to.meta.needLogin&&unLogined){//需要登录并且没有登录
next('/login')//跳到登录页
}else{
next();//不需要登录
}
}
2.全局解析守卫(router.beforeResolve)
在 2.5.0+ 你可以用 router.beforeResolve 注册一个全局守卫。这和 router.beforeEach 类似,区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用。
全局后置钩子(router.afterEach)
router.afterEach((to, from) => {
// 一个导航完成后执行的函数,不用next回调,对路由的跳转也没有影响
})
路由独享的守卫(routes里边配置beforeEnter)
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// 跳转到当前路由路由时调用
}
}
]
})
组件内的守卫
(beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave)
const Foo = {
template: `...`,
beforeRouteEnter (to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
}
离开守卫通常用来禁止用户在还未保存修改前突然离开。该导航可以通过 next(false) 来取消。
Foo={
template:'<div>foo</div>',
beforeRouterLeave:function(to,from,next){
if (saved) {//保存了
next()
} else {
next(false)
}
}
}
路由元信息(meta)
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
children: [
{
path: 'bar',
component: Bar,
// a meta field
meta: { requiresAuth: true }
}
]
}
]
})
一个路由匹配到的所有路由记录会暴露为 route.matched 数组。因此,我们需要遍历 $route.matched 来检查路由记录中的 meta 字段。
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {//判断路由记录中有没有需要登录的路由
// this route requires auth, check if logged in
// if not, redirect to login page.
if (!auth.loggedIn()) {//判断用户是否已经登录(如果没有登录就跳到登录页)
next({
path: '/login',
query: { redirect: to.fullPath }
})
} else {
next()
}
} else {
next() // 确保一定要调用 next()
}
})
网友评论