vue-router进阶

2019-01-11  本文已影响0人  Mr无愧于心

导航守卫

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 对象 (还有在导航守卫中的路由对象) 的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()
  }
})
上一篇下一篇

猜你喜欢

热点阅读