路由

Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。包含的功能有:

  • 嵌套的路由/视图表
  • 模块化的、基于组件的路由配置
  • 路由参数、查询、通配符
  • 基于 Vue.js 过渡系统的视图过渡效果
  • 细粒度的导航控制
  • 带有自动激活的 CSS class 的链接
  • HTML5 历史模式或 hash 模式,在 IE9 中自动降级
  • 自定义的滚动条行为
  1. const User = {
  2. // 获取参数
  3. template: '<div>User {{$route.params.id}}</div>'
  4. }
  5. const router = new VueRouter({
  6. routes: [
  7. // 动态路径参数 以冒号开头
  8. { path: '/user/:id', component: User }
  9. ]
  10. })

路由传参

  • $route.params

    1. { path: '/user/:id', component: User }
  • $route.query

    1. router.push({ path: 'register', query: { plan: 'private' }})

    模式

vue-router 默认 hash 模式 —— 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载。
如果不想要很丑的 hash,我们可以用路由的 history 模式,这种模式充分利用 history.pushState API 来完成 URL 跳转而无须重新加载页面。

HTML5 History 模式

  1. const router = new VueRouter({
  2. mode: 'history',
  3. routes: [...]
  4. })

需要服务端配置

  1. location / {
  2. try_files $uri $uri/ /index.html;
  3. }

编程式导航

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

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

声明式 编程式
<router-link :to="..."> router.replace(...)
  1. // 字符串
  2. router.push('home')
  3. // 对象
  4. router.push({ path: 'home' })
  5. // 命名的路由
  6. router.push({ name: 'user', params: { userId: '123' }})
  7. // 带查询参数,变成 /register?plan=private
  8. router.push({ path: 'register', query: { plan: 'private' }})

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

声明式 编程式
<router-link :to="..." replace> router.replace(...)
  1. // 跟 router.push 很像,唯一的不同就是,它不会向 history 添加新记录,
  2. // 而是跟它的方法名一样 —— 替换掉当前的 history 记录。
  3. router.replace(location, onComplete?, onAbort?)
  4. // 在浏览器记录中前进一步,等同于 history.forward()
  5. router.go(1)
  6. // 后退一步记录,等同于 history.back()
  7. router.go(-1)

router.go(n)

  1. // 前进 3 步记录
  2. router.go(3)

路由守卫

全局守卫

前置守卫

  1. // GOOD
  2. router.beforeEach((to, from, next) => {
  3. if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' })
  4. else next()
  5. })

后置守卫

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

路由独享的守卫

  1. const router = new VueRouter({
  2. routes: [
  3. {
  4. path: '/foo',
  5. component: Foo,
  6. beforeEnter: (to, from, next) => {
  7. // ...
  8. }
  9. }
  10. ]
  11. })

这些守卫与全局前置守卫的方法参数是一样的。

组件内的守卫

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

  • beforeRouteEnter
  • beforeRouteUpdate (2.2 新增)
  • beforeRouteLeave
    1. const Foo = {
    2. template: `...`,
    3. beforeRouteEnter(to, from, next) {
    4. // 在渲染该组件的对应路由被 confirm 前调用
    5. // 不!能!获取组件实例 `this`
    6. // 因为当守卫执行前,组件实例还没被创建
    7. },
    8. beforeRouteUpdate(to, from, next) {
    9. // 在当前路由改变,但是该组件被复用时调用
    10. // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
    11. // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    12. // 可以访问组件实例 `this`
    13. },
    14. beforeRouteLeave(to, from, next) {
    15. // 导航离开该组件的对应路由时调用
    16. // 可以访问组件实例 `this`
    17. }
    18. }