vue-router用法记录

Vue-Router简介

Vue-Router是Vue.js官方维护的路由插件,同时也是官方推荐的路由插件。它与Vue.js内核深度结合,让开发单页应用更加容易简便。

基本配置

  • **HTML **

对应的路由匹配成功,将自动设置 class 属性值 .router-link-active

Hello App!

Go to Foo Go to Bar

  • JavaScript
Vue.use(VueRouter)

//定义路由
const routes = [
  { path: '/foo', component: Foo },
  { path: '/bar', component: Bar }
]

//创建router实例
const router = new VueRouter({
  routes // (缩写)相当于 routes: routes
})

//挂载实例
const app = new Vue({
  router
}).$mount('#app')

动态路由配置

  • 场景:通过URL传递参数

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

    动态路径参数使用冒号:标记,对应的值都会设置到 $route.params中。此处可通过this.$route.params.id来获取id,在模板中可以省略this.,如

    const User = {
      template: '
    User {{ $route.params.id }}
    ' }
  • 如果是非必须的参数,可在参数后加一个?,如path:''/page1/:id?'对于带查询参数的URL,如 /page1?id=123可用 $route.query 访问,如果没有查询参数,则是个空对象。

响应路由参数的变化

当使用路由参数时,例如从 /page1/123 导航到 /page1/321,原来的组件实例会被复用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用。

复用组件时,想对路由参数的变化作出响应的话,你可以简单地watch(监测变化) $route 对象。

watch: {
  '$route' (to, from) {
    // 对路由变化作出响应...
  }
}

或者使用 2.2 中引入的 beforeRouteUpdate 守卫:

beforeRouteUpdate (to, from, next) {
    // react to route changes...
    // don't forget to call next()
  }

嵌套路由

实际生活中的应用界面,通常由多层嵌套的组件组合而成。同样地,URL 中各段动态路径也按某种结构对应嵌套的各层组件。借助 vue-router,使用嵌套路由配置,就可以很简单地表达这种关系。

使用 children 配置

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

编程式导航

除了使用 创建a 标签来定义导航链接,我们还可以借助router 的实例方法,通过编写代码来实现。

// 字符串
router.push('home')

// 对象
router.push({ path: 'home' })

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

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

注意:如果提供了 path,params 会被忽略

const userId = 123
router.push({ name: 'user', params: { userId }}) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
// 这里的 params 不生效
router.push({ path: '/user', params: { userId }}) // -> /user

命名路由

有时候,通过一个名称来标识一个路由显得更方便一些,特别是在链接一个路由,或者是执行一些跳转的时候。命名路由可以通过$route.name来获取名称。

const router = new VueRouter({
  routes: [
    {
      path: '/user/:userId',
      name: 'user',
      component: User
    }
  ]
})

路由元信息

定义路由的时候可以配置meta 字段。可通过$route.meta访问。

{
   path: '/user/:userId',
   name: 'user',
   component: User,
   meta: {
     title: 'user'
   }
}

全局钩子和路由独享的钩子

正如其名,vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。有多种机会植入路由导航过程中:全局的, 单个路由独享的, 或者组件级的。

记住参数或查询的改变并不会触发进入/离开的导航守卫。你可以通过观察 $route 对象来应对这些变化,或使用 beforeRouteUpdate 的组件内守卫。

  • 全局守卫

    你可以使用 router.beforeEach 注册一个全局前置守卫:

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

    当一个导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于 等待中

    每个守卫方法接收三个参数:

    • to: Route: 即将要进入的目标 路由对象
    • from: Route: 当前导航正要离开的路由
    • next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。
      • next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
      • next(false): 中断当前的导航。如果浏览器的 URL 改变了(可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
      • next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。
      • next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。

    确保要调用 next 方法,否则钩子就不会被 resolved。

  • 全局解析守卫

    在 2.5.0+ 你可以用 router.beforeResolve 注册一个全局守卫。这和 router.beforeEach 类似,区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用。

  • 全局后置钩子

    你也可以注册全局后置钩子,然而和守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身:

    router.afterEach((to, from) => {
      // ...
    })
    
  • 路由独享的守卫

    const router = new VueRouter({
      routes: [
        {
          path: '/foo',
          component: Foo,
          beforeEnter: (to, from, next) => {
            // ...
          }
        }
      ]
    })
    
  • 组件内的守卫

    最后,你可以在路由组件内直接定义以下路由导航守卫:

    • beforeRouteEnter
    • beforeRouteUpdate (2.2 新增)
    • 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`
      }
    }
    

你可能感兴趣的:(vue-router用法记录)