基本步骤
- 安装 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
的to
prop 或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({ |
组件内的守卫
可以在路由组件内直接定义以下路由导航守卫:
beforeRouteEnter
beforeRouteUpdate
(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