一、介绍
Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。包含的功能有:
- 嵌套的路由/视图表
- 模块化的、基于组件的路由配置
- 路由参数、查询、通配符
- 基于 Vue.js 过渡系统的视图过渡效果
- 细粒度的导航控制
- 带有自动激活的 CSS class 的链接
- HTML5 历史模式或 hash 模式,在 IE9 中自动降级
- 自定义的滚动条行为
二、安装
npm install vue-router
如果在一个模块化工程中使用它,通过 Vue.use() 明确地安装路由功能:
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
三、使用
1.src/router.js
import Vue from 'vue'
import Router from 'vue-router'
// 1.组件可以从其他文件 import 进来
// 也可以定义 (路由) 组件。
import Home from './views/Home.vue'
//要告诉 vue 使用 vueRouter
Vue.use(Router)
// 2. 定义路由
// 每个路由应该映射一个组件。 其中"component" 可以是通过 Vue.extend() 创建的组件构造器,
// 或者,只是一个组件配置对象。
const routes = [
{
path: '/',
name: 'home',
component: Home
},
{
path: '/about',
name: 'about',
component: () => import(/* webpackChunkName: "about" */ './views/About.vue')
}
]
// 3. 创建 router 实例,然后传 `routes` 配置
var router = new VueRouter({
// mode:'history',
routes // (缩写) 相当于 routes: routes
})
export default router;
1.main.js中
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
Vue.config.productionTip = false
// 4. 创建和挂载根实例。
// 记得要通过 router 配置参数注入路由,从而让整个应用都有路由功能
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
3.HTML中
<div>
<h1>Hello App!</h1>
<p>
<!-- 使用 router-link 组件来导航. -->
<!-- 通过传入 `to` 属性指定链接. -->
<!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
<router-link to="/home">Go to Home</router-link>
<router-link to="/about">Go to About</router-link>
</p>
<!-- 路由出口 -->
<!-- 路由匹配到的组件将渲染在这里 -->
<router-view></router-view>
</div>
4.跳转
// Home.vue
通过注入路由器,我们可以在任何组件内通过 this.$router
访问路由器,也可以通过 this.$route
访问当前路由:
export default {
methods: {
goBack() {
window.history.length > 1 ? this.$router.go(-1) : this.$router.push('/')
}
}
}
四、动态路由匹配
const User = {
template: '<div>User</div>'
}
const router = new VueRouter({
routes: [
// 动态路径参数 以冒号开头
{ path: '/user/:id', component: User }
]
})
像 /user/foo 和 /user/bar 都将映射到相同的路由,匹配到一个路由时,参数值会被设置到 this.$route.params,可以在每个组件内使用。
还可以在一个路由中设置多段“路径参数”,对应的值都会设置到 $route.params 中。例如:
模式 | 路径 | $route.params |
---|---|---|
/user/:username | /user/evan | { username: ‘evan’ } |
/user/:username/post/:post_id | /user/evan/post/123 | { username: ‘evan’, post_id: ‘123’ } |
五、响应路由参数的变化
当使用路由参数时,例如从 /user/foo 导航到 /user/bar,原来的组件实例会被复用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用。
复用组件时,想对路由参数的变化作出响应的话,可以简单地 watch
(监测变化) $route
对象:
watch: {
$route(to, from) {
// 对路由变化作出响应...
}
}
六、嵌套路由
实际生活中的应用界面,通常由多层嵌套的组件组合而成,此时可以使用children来解决。
const router = new VueRouter({
routes: [
{
path: '/user/:id',
component: User,
children: [
{
path: '',// /user未指定子路由时,默认指定一个路由
component: UserProfile
},
{
// 当 /user/:id/profile 匹配成功,
// UserProfile 会被渲染在 User 的 <router-view> 中
path: 'profile',
component: UserProfile
},
{
// 当 /user/:id/posts 匹配成功
// UserPosts 会被渲染在 User 的 <router-view> 中
path: 'posts',
component: UserPosts
}
]
}
]
})
七、编程式导航
除了使用 <router-link>
创建 a
标签来定义导航链接,我们还可以借助 router
的实例方法,通过编写代码来实现。
router.push(location, onComplete?, onAbort?)
在 Vue 实例内部,你可以通过 $router
访问路由实例。因此你可以调用 this.$router.push
,以下展示几种调用方式:
// 字符串
router.push('home')
// 对象
router.push({ path: 'home' })
// 命名的路由
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
八、路由懒加载
当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。结合 Vue 的异步组件 和 Webpack 的代码分割功能,轻松实现路由组件的懒加载。
在 Webpack 2 中,我们可以使用动态 import 语法来定义代码分块点
const Foo = () => import('./Foo.vue')
在路由配置中什么都不需要改变,只需要像往常一样使用 Foo:
const router = new VueRouter({
routes: [{ path: '/foo', component: Foo }]
})
有时候我们想把某个路由下的所有组件都打包在同个异步块 (chunk) 中。只需要使用 命名 chunk
,一个特殊的注释语法来提供 chunk name (需要 Webpack > 2.4)。
const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue')
const Bar = () => import(/* webpackChunkName: "group-foo" */ './Bar.vue')
const Baz = () => import(/* webpackChunkName: "group-foo" */ './Baz.vue')