基本步骤
- 安装 vue-router
- 导入路由对象,Vue.use(VueRouter)
- 创建路由实例,并配置路由映射关系(路由组件映射关系)
- Vue 实例挂载路由实例
安装
生产依赖
1 | $ npm install vue-router --save |
导入路由对象
1 | // ./router/index.js |
创建路由实例
- 引入路由组件
- 创建路由对象实例,并设置路由映射规则
1 | // ./router/index.js |
路由对象实例属性:
routes: 路由映射规则;mode: 路由模式,可设置history,默认hash;linkActiveClass: 整体设置router-link选中样式,默认router-link-active;
挂载路由
1 | // ./main.js |
使用
<router-link>及属性
利用 <router-link> 跳转路由
属性:
to: 路由路径;tag: 渲染标签,默认渲染成<a>标签;active-class: 选中样式,默认router-link-active;replace: 路由跳转设置成替换(不可返回/前进),默认为push(有路径记录);
1 | <router-link to="/home" tag="li" replace active-class="li-active">首页</router-link> |
<router-view>及命名视图
<router-view> 路由出口
当同级有多个视图时,可使用命名视图。如果 router-view 没有设置名字,那么默认为 default。
1 | <router-view></router-view> |
而多视图时路由规则配置如下:
1 | const router = new VueRouter({ |
命名路由
设置路由规则时,可以设置一个名称来标示某个路由,在使用动态路由时传递参数时更加方便。可以在创建 Router 实例的时候,在 routes 配置中给某个路由设置名称。
1 | const router = new VueRouter({ |
<router-link> 链接命名路由则需要给 to 属性传入一个对象:
1 | <router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link> |
通过代码跳转路由 $router.push() 时同样要传入一个对象:
1 | router.push({ name: 'user', params: { userId: 123 } }) |
路由嵌套
- 路由对象中规则对应组件添加
children属性,配置子路由; - 对应组件中添加
<router-view>,及路由跳转设置;
1 | // ./router/index.js |
1 | <!-- ./components/Home.vue --> |
$router 路由对象
$router.push(): 路径跳转;$router.replace(): 路径替换;
1 | export default { |
传递查询信息,$router.push() 中传入一个对象,并设置 query 对象:
1 | export default { |
$route 路由信息
$route.params.xxx: 动态路由参数;$route.query.xxx: 路由查询;
基本设置
1 | // ./router/index.js |
1 | <!-- ./components/App.vue --> |
获取动态路由参数
1 | <!-- ./components/User.vue --> |
获取路由查询信息
1 | <!-- ./components/Profile.vue --> |
路由懒加载
方式一:结合 Vue 的异步组件和 Webpack 的代码分析;
1 | const Home = resolve => { |
方式二:AMD 写法
1 | const Home = (resolve) => require(['../components/Home.vue'], resolve) |
方式三:ES6 中更加简便的 Vue 异步组件和 Webpack 的代码分割写法(推荐且常用)
1 | // ./router/index.js |
路由守卫
完整导航流程
- 导航被触发。
- 在失活的组件里调用离开守卫。
- 调用全局的
beforeEach守卫。 - 在重用的组件里调用
beforeRouteUpdate守卫 (2.2+)。 - 在路由配置里调用
beforeEnter。 - 解析异步路由组件。
- 在被激活的组件里调用
beforeRouteEnter。 - 调用全局的
beforeResolve守卫 (2.5+)。 - 导航被确认。
- 调用全局的
afterEach钩子。 - 触发
DOM更新。 - 用创建好的实例调用
beforeRouteEnter守卫中传给next的回调函数。
router.beforeEach 全局前置守卫
1 | const router = new VueRouter({ ... }) |
每个守卫方法接收三个参数:
to: Route: 即将要进入的目标 路由对象from: Route: 当前导航正要离开的路由next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。next(false): 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。next('/')或者next({ path: '/' }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向 next 传递任意位置对象,且允许设置诸如replace: true、name: 'home'之类的选项以及任何用在router-link的toprop 或router.push中的选项。next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给router.onError()注册过的回调。
确保要调用 next 方法,否则钩子就不会被 resolved。
router.afterEach 全局后置钩子
和守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身:
1 | router.afterEach((to, from) => { |
路由独享的守卫
可以在路由配置上直接定义 beforeEnter 守卫:
1 | const router = new VueRouter({ |
组件内的守卫
可以在路由组件内直接定义以下路由导航守卫:
beforeRouteEnterbeforeRouteUpdate(2.2 新增)beforeRouteLeave
1 | const Foo = { |
keep-alive 与路由
将 <router-view> 用 <keep-alive> 包裹起来,可保持缓存组件,不会每次路由跳转时都销毁组件。
注意:缓存的同时 created、destroyed 等生命周期函数在二次进入组件时都不会被调用。但可以使用 activated、deactivated 钩子函数来替代,这两个钩子函数也只能在 keep-alive 组件中才能使用。
1 | <template> |
keep-alive 标签属性:
include- 字符串或正则表达式。只有名称匹配的组件会被缓存。2.1.0 新增exclude- 字符串或正则表达式。任何名称匹配的组件都不会被缓存。2.1.0 新增max- 数字。最多可以缓存多少组件实例。2.5.0 新增
1 | <!-- 逗号分隔字符串 --> |
include、exclude 匹配首先检查组件自身的 name 选项,如果 name 选项不可用,则匹配它的局部注册名称 (父组件 components 选项的键值)。匿名组件不能被匹配。
参考文献:
- Vuejs.org - Vue Router




