认识 vue-router
vue-router是Vue.js官方的路由插件,它和vue.js是深度集成的,适合用于构建单页面应用。
我们可以访问其官方网站对其进行学习: https://router.vuejs.org/zh/
vue-router是基于路由和组件的:
路由用于设定访问路径, 将路径和组件映射起来。
在vue-router的单页面应用中, 页面的路径的改变就是组件的切换。
安装和使用 vue-router
安装vue-router
1 | npm install vue-router --save |
在模块化工程中使用
第一步:导入路由对象,并且调用 Vue.use(VueRouter)
第二步:创建路由实例,并且传入路由映射配置
第三步:在Vue实例中挂载创建的路由实例
1 | import Vue from 'vue' |
使用 vue-router 的步骤
第一步: 创建路由组件
第二步: 配置路由映射: 组件和路径映射关系
第三步: 使用路由: 通过
<router-link>
和<router-view>
操作演示
创建 router 实例
挂载到Vue实例中
创建路由组件
配置组件和路径的映射关系
使用路由
说明:
<router-link>
: 该标签是一个vue-router中已经内置的组件, 它会被渲染成一个<a>
标签.<router-view>
: 该标签会根据当前的路径, 动态渲染出不同的组件.- 网页的其他内容, 比如顶部的标题/导航, 或者底部的一些版权信息等会和
<router-view>
处于同一个等级.
在路由切换时, 切换的是<router-view>
挂载的组件, 其他内容不会发生改变.
效果
设置路由的默认路径
需求:默认情况下, 进入网站的首页, 我们希望<router-view>
渲染首页的内容.但是我们的实现中, 默认没有显示首页组件, 必须让用户点击才可以.
问题:如何可以让路径默认跳到到首页, 并且<router-view>
渲染首页组件呢?
方案:多配置一个映射
配置解析:
- 我们在routes中又配置了一个映射.
- path配置的是根路径: /
- redirect是重定向, 也就是我们将根路径重定向到/home的路径下, 这样就可以得到我们想要的结果了
History 模式
History模式:路径显示中不含 # (vue默认路径显示方式为hash模式,路径中带有#,可以参考上面的运行截图)
如果希望使用HTML5的history模式, 非常简单, 进行如下配置即可:
效果:
router-link 补充
一些属性
tag: 可以指定<router-link>
之后渲染成什么组件, 比如下面的代码会被渲染成一个<li>
元素, 而不是<a>
1 | <router-link to='/home' tag='li'> |
replace: replace不会留下history记录, 所以指定replace的情况下, 后退键返回不能返回到上一个页面中
active-class: 当<router-link>
对应的路由匹配成功时, 会自动给当前元素设置一个router-link-active
的class, 设置active-class
可以修改默认的名称。在进行高亮显示的导航菜单或者底部tabbar时, 会使用到该类.
但是通常不会修改类的属性, 会直接使用默认的router-link-active即可.
该class具体的名称也可以通过router实例的属性进行修改:
可以看到 后面第二个class的名称变成了 active
路由代码跳转
有时候, 页面的跳转可能需要执行对应的JavaScript代码, 这个时候, 就可以使用第二种跳转方式了
比如, 我们将代码修改如下:
动态路由
在某些情况下,一个页面的path路径可能是不确定的,比如我们进入用户界面时,希望是如下的路径:
/user/zhangsan或/user/lisi
除了有前面的/user之外,后面还跟上了用户的ID,这种path和Component的匹配关系,我们称之为动态路由(也是路由传递数据的一种方式)。
方式:
1 | path: '/user/:id' |
懒加载
官方解释:当打包构建应用时,Javascript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了
懒加载做了什么?
- 路由懒加载的主要作用就是将路由对应的组件打包成一个个的js代码块.
- 只有在这个路由被访问到的时候, 才加载对应的组件
方式
在ES6中, 我们有更加简单的写法:
1 | const Home = () => import('../components/home.vue') |
效果
嵌套路由
概述
嵌套路由是一个很常见的功能
- 比如在home页面中, 我们希望通过/home/news和/home/message访问一些内容.
- 一个路径映射一个组件, 访问这两个路径也会分别渲染两个组件.
路径和组件关系如下:
步骤
- 创建对应的子组件, 并且在路由映射中配置对应的子路由.
- 在组件内部使用
<router-view>
标签.
使用演示
创建home页面的两个字组件页面 message 页面 和 news 页面
因为创建的两个组件是home下的,因此在配置路径时,为home添加children属性,并在children内配置message和news的路径(不加 斜杠 /),如下
在home页面配置字组件的路由连接和显示 通过 <router-link>
和 <router-view>
标签
效果
嵌套路由默认路径
配置示意如下:
传递参数
方式
params的类型:
- 配置路由格式: /router/:id
- 传递的方式: 在path后面跟上对应的值
- 传递后形成的路径: /router/123, /router/abc
query的类型:
query是对象的形式,变量 key-value 方式存在
配置路由格式: /router, 也就是普通配置
- 传递的方式: 对象中使用query的key作为传递方式
- 传递后形成的路径: /router?id=123, /router?id=abc
示例:
1
2
3
4
5// params 类型 to 绑定的相当于一个字符串
<router-link :to="'/user/'+userId">用户</router-link>
//query 类型 to 绑定的相当于一个对象,对象内有两个变量 path 和 query,并且query也是对象的形式
<router-link :to="{path: '/profile',query: {name: 'zx',id: userId}}">档案</router-link>
使用
使用也有两种方式:
<router-link>
的方式JavaScript
代码方式
操作演示 - <router-link>
方式
先创建一个新的组件Profile.vue,并配置好路由映射
配置router-link
可以明显看出,和 params 方式的不同之处:params
操作演示 JavaScript方式
也是很简单,调用this.$router.push() 里面传入一个对象即可,对象包含两个变量 一个path,一盒query
获取传递的参数
获取 params 方式传递的参数:
1
$route.params
获取 query 方式传递的参数:
1
2
3
4//获取整个query对象
$route.query
//获取query对象中的某个key的value值
$route.query.name
获取参数通过$route
对象获取的,在使用了vue-router
的应用中,路由对象会被注入每个组件中,赋值为this.$route
,并且当路由切换时,路由对象会被更新。获取传递的信息如下:
$route
和$router
的区别
$router
为VueRouter实例,想要导航到不同URL,则使用$router.push
方法$route
为当前router跳转对象里面可以获取name、path、query、params
等
导航守卫
官网
vue-router提供的导航守卫主要用来监听监听路由的进入和离开的.
vue-router提供了beforeEach和afterEach的钩子函数, 它们会在路由即将改变前和改变后触发.
beforeEach
1 | router.beforeEach((to, from, next) => { |
导航钩子的三个参数解析:
to: 即将要进入的目标的路由对象。
from: 当前导航即将要离开的路由对象。
next: 调用该方法后, 才能进入下一个钩子. 该方法必须调用,否则无法完成正常跳转。
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() 注册过的回调。
afterEach
1 | router.afterEach((to, from) => { |
简单示例:beforeEach改变页面标题
路由独享守卫
上面我们使用的导航守卫, 被称之为全局守卫.
可以在路由配置上直接定义 beforeEnter 守卫:
这些守卫与全局前置守卫的方法参数是一样的。
1 | const router = new VueRouter({ |
组件内的守卫
可以在路由组件内直接定义以下路由导航守卫:
beforeRouteEnter
beforeRouteUpdate
(2.2 新增)beforeRouteLeave
1 | const Foo = { |
这个离开守卫通常用来禁止用户在还未保存修改前突然离开。该导航可以通过 next(false)
来取消。
1 | beforeRouteLeave (to, from , next) { |
keep-alive
- keep-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。
它有两个非常重要的属性:- include - 字符串或正则表达,只有匹配的组件会被缓存
- exclude - 字符串或正则表达式,任何匹配的组件都不会被缓存
- router-view 也是一个组件,如果直接被包在 keep-alive 里面,所有路径匹配到的视图组件都会被缓存:
1 | //取消缓存某个组件,注意exclude后面的多个组件名之间不能有空格 |