vue-router

1.安装

npm install vue-router

import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)

2.使用

需要在vue实例化时,将router挂载到实例对象上。

// html结构
<div id="app">
  <h1>Hello App!</h1>
  <p>
    <!-- 使用 router-link 组件来导航. -->
    <!-- 通过传入 `to` 属性指定链接. -->
    <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
    <router-link to="/foo">Go to Foo</router-link>
    <router-link to="/bar">Go to Bar</router-link>
  </p>
  <!-- 路由出口 -->
  <!-- 路由匹配到的组件将渲染在这里 -->
  <router-view></router-view>
</div>
// 路由脚本挂载
// 0. 如果使用模块化机制编程,导入Vue和VueRouter,要调用 Vue.use(VueRouter)

// 1. 定义 (路由) 组件。
// 可以从其他文件 import 进来
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }
// 2. 定义路由
// 每个路由应该映射一个组件。 其中"component" 可以是
// 通过 Vue.extend() 创建的组件构造器,
// 或者,只是一个组件配置对象。
// 我们晚点再讨论嵌套路由。
const routes = [
  { path: '/foo', component: Foo },
  { path: '/bar', component: Bar }
]
// 3. 创建 router 实例,然后传 `routes` 配置
// 你还可以传别的配置参数, 不过先这么简单着吧。
const router = new VueRouter({
  routes // (缩写) 相当于 routes: routes
})
// 4. 创建和挂载根实例。
// 记得要通过 router 配置参数注入路由,
// 从而让整个应用都有路由功能
const app = new Vue({
  router
}).$mount('#app')

通过注入路由器,我们可以在任何组件内通过this.$router访问路由器,也可以通过this.$route访问当前路由。

this.$router.go(-1)
this.$router.push('/')

当然,一般项目中会将路由模块化:

import Vue from 'vue'
import Router from 'vue-router'
// 以下引入为页面的vue文件
import Page404 from '@/views/Page404.vue'
import Home from '@/views/Home.vue'
import Loan from '@/views/Loan.vue'
import LoanChart from '@/views/LoanChart.vue'
import RepayChart from '@/views/RepayChart.vue'
import LoanHistory from '@/views/LoanHistory.vue'
import LoanList from '@/views/LoanList.vue'
import DoRepay from '@/views/DoRepay.vue'
Vue.use(Router) // 初始化路由
export default new Router({ // 返回路由实例
  mode: 'history', // history模式:不使用hash作为路由跳转依据,而使用正常的网页路径,服务器路由需要配置好主页面跳转
  base: process.env.BASE_URL, // 基础url
  routes: [ // 具体路由列表
    {
      path: '/',
      name: 'home', // 路由命名后,使用路由跳转会更加方便
      component: Home
    },
    {
      path: '/loan',
      name: 'loan',
      component: Loan
    },
    {
      path: '/loanList',
      name: 'loanList',
      component: LoanList
    },
    {
      path: '/doRepay/:id', // 路由动态参数
      name: 'doRepay',
      component: DoRepay
    },
    {
        path: '*',
        name: 'Page404',
        component: Page404
    }
  ]
})

3.动态路由

this.$route.params对象中包含/:id传参;
this.$route.query对象中包含?aid=1的query传参;
若路由是同一个,但仅仅是路由的参数不同,vue则会利用原来的组件实例进行渲染而不会销毁后重新创建。因此,组件的生命周期也不会全部重新调用。
若需要监听路由变化,可以有以下两种方法:

// 在组件中检测$watch对象
watch: {
'$route' (to, from) {
  // 对路由变化作出响应...
}
}

// 使用beforeRouteUpdate钩子函数
beforeRouteUpdate (to, from, next) {
// react to route changes...
// don't forget to call next()
}

路由按定义的先后顺序进行匹配,具体匹配规则与细则可参阅文档 https://github.com/pillarjs/path-to-regexp#parameters

4.嵌套路由

当路由需要往下嵌套时,路由定义也十分方便:

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

5. 编程导航

在vue实例内部,可以使用this.$router访问路由实例。
路由跳转: 使用this.$router.push(url)实现同<router-link :to="url">点击一样的效果。push参数如下:

router.push('home') // 字符串
router.push({ path: 'home' }) // 对象
router.push({ name: 'user', params: { userId: '123' }}) // 命名的路由
router.push({ path: 'register', query: { plan: 'private' }}) // 带查询参数的路由

若提供的path参数,params参数会被忽略,但query参数不会。同时,pushreplace方法还存在第二个参数onComplete和第三个参数onAbort,分别代表导航成功完成和终止的时候的钩子函数。
replace方法同push类似,只不过是替换当前路由而不是新添加路由。
go方法同window.history.go(n)

6. 命名视图

当同一个组件或页面中有两个或者多个<router-view>视图需要同时不同展示时,需要使用命名视图:

<router-view class="view one"></router-view>
<router-view class="view two" name="a"></router-view>
<router-view class="view three" name="b"></router-view>
const router = new VueRouter({
  routes: [
    {
      path: '/',
      components: { // 注意是components
        default: Foo,
        a: Bar,
        b: Baz
      }
    }
  ]
})

7. 重定向

const router = new VueRouter({
  routes: [
    { path: '/a', redirect: '/b' },
    { path: '/c', redirect: { name: 'foo' } },
    { path: '/d', redirect: to => {
                // 方法接收 目标路由 作为参数 to = '/d'
          // return 重定向的 字符串路径/路径对象
        }
    }
  ]
})

8. 别名

当用户访问/b路由时,url显示的/b路由,但是展示的却是/a路由的内容,称/b路由是/a路由的别名。

const router = new VueRouter({
  routes: [
    { path: '/a', component: A, alias: '/b' } // 访问/a路由与/b路由一样
  ]
})

9. 路由组件传参

若路由的传参都需要通过$router去获取的话,导致组件就只能在某些特定的路由下使用,不利于组件的复用。故定义时,可以使用组件的props去接受路由参数。

const User = {
  props: ['id'],
  template: '<div>User {{ id }}</div>'
}

const router = new VueRouter({
  routes: [
    { path: '/user/:id', component: User, props: true },
    // 对于包含命名视图的路由,你必须分别为每个命名视图添加 `props` 选项:
    {
      path: '/user/:id',
      components: { default: User, sidebar: Sidebar },
      props: { default: true, sidebar: false }
    }
  ]
})

布尔模式:如果props被设置为trueroute.params将会被设置为组件属性。
对象模式:如果props是一个对象,它会被按该对象原样设置为组件属性,也就是将props对象内容传递到组件内。当props是静态的时候有用。
函数模式:你可以创建一个函数返回props

const router = new VueRouter({
  routes: [
    { path: '/search', component: SearchUser, props: (route) => ({ query: route.query.q }) }
  ]
})
// "/search?q=vue" 会将 {query: 'vue'} 作为属性传递给 SearchUser 组件