全家桶vue-router 学习使用笔记


一、 动态路由匹配

一个“路径参数”使用冒号 : 标记。当匹配到一个路由时,参数值会被设置到 this.$route.params,可以在每个组件内使用

const User = {
    
    
  template: '<div>User</div>'
}

const router = new VueRouter({
    
    
  routes: [
    // 动态路径参数 以冒号开头
    {
    
     path: '/user/:id', component: User }
  ]
})

const User = {
    
    
  template: '<div>User {
    
    { $route.params.id }}</div>'
}

当使用路由参数时,例如从 /user/foo 导航到 /user/bar,原来的组件实例会被复用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。
1不过,这也意味着组件的生命周期钩子不会再被调用。想对路由参数的变化作出响应的话,你可以简单地 watch (监测变化) $route
2 引入的 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()
  }
}

二、嵌套路由

是最顶层的出口,渲染最高级路由匹配到的组件,在嵌套的出口中渲染组件,需要在 VueRouter 的参数中使用 children 配置:

const router = new VueRouter({
    
    
  routes: [
    {
    
     path: '/user/:id', component: User,
      children: [
        {
    
    
          // 当 /user/:id/profile 匹配成功,
          // UserProfile 会被渲染在 User 的 <router-view> 中
          path: 'profile',
          component: UserProfile
        },
        {
    
    
          // 当 /user/:id/posts 匹配成功
          // UserPosts 会被渲染在 User 的 <router-view> 中
          path: 'posts',
          component: UserPosts
        }
      ]
    }
  ]
})

三、命名视图

一个视图使用一个组件渲染,因此对于同个路由,多个视图就需要多个组件。确保正确使用 components 配置 (带上 s):

const router = new VueRouter({
    
    
  routes: [
    {
    
    
      path: '/',
      components: {
    
    
        default: Foo,
        a: Bar,
        b: Baz
      }
    }
  ]
})

四、编程式的导航

借助 router 的实例方法,通过编写代码来实现。

router.push(location, onComplete?, onAbort?)

这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的 URL。
注意:如果提供了 path,params 会被忽略,上述例子中的 query 并不属于这种情况。取而代之的是下面例子的做法,你需要提供路由的 name 或手写完整的带有参数的 path:

// 命名的路由
router.push({
    
     name: 'user', params: {
    
     userId: '123' }})

// 带查询参数,变成 /register?plan=private
router.push({
    
     path: 'register', query: {
    
     plan: 'private' }})

router.replace(location, onComplete?, onAbort?)

跟 router.push 很像,唯一的不同就是,它不会向 history 添加新记录,而是跟它的方法名一样 —— 替换掉当前的 history 记录。

router.go(n)

这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似 window.history.go(n)。

五、导航守卫

导航守卫主要用来通过跳转或取消的方式守卫导航。有多种机会植入路由导航过程中:全局的, 单个路由独享的, 或者组件级的。
导航被触发。
在失活的组件里调用 beforeRouteLeave 守卫。
调用全局的 beforeEach 守卫。
在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
在路由配置里调用 beforeEnter。
解析异步路由组件。
在被激活的组件里调用 beforeRouteEnter。
调用全局的 beforeResolve 守卫 (2.5+)。
导航被确认。
调用全局的 afterEach 钩子。
触发 DOM 更新。
调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。

router.beforeEach 全局前置守卫

const router = new VueRouter({
    
     ... })

router.beforeEach((to, from, next) => {
    
    
  // ...
})

用户未能验证身份时重定向到 /login

router.beforeEach((to, from, next) => {
    
    
  if (to.name !== 'Login' && !isAuthenticated) next({
    
     name: 'Login' })
  else next()
})

router.afterEach全局后置钩子

router.afterEach((to, from) => {
    
    
  // ...
})

beforeEnter 路由独享的守卫

const router = new VueRouter({
    
    
  routes: [
    {
    
    
      path: '/foo',
      component: Foo,
      beforeEnter: (to, from, next) => {
    
    
        // ...
      }
    }
  ]
})

** 组件内的守卫**

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`
  }
}

beforeRouteEnter 守卫 不能 访问 this,因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建。

不过,你可以通过传一个回调给 next来访问组件实例。在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数。

beforeRouteEnter (to, from, next) {
    
    
  next(vm => {
    
    
    // 通过 `vm` 访问组件实例
  })
}

猜你喜欢

转载自blog.csdn.net/cyadyx/article/details/108472919