![a161f91e1673422dbebdee81081b5681.png](https://img-blog.csdnimg.cn/img_convert/a161f91e1673422dbebdee81081b5681.png)
大家好,在上一篇系列文章里「vue基础」一篇浅显易懂的 Vue 路由使用指南( Vue Router 上),我们一起学习了路由的基本配置,如何创建路由和传参,本篇文章我们一起学习下 Navigation 导航和路由守卫的相关内容。
Navigation
如果要改变当前路径,我们可以使用 自带的组件和JS编码的两种方式进行实现。
一、 Links方式
尽管你可以使用标准的标签功能进行实现,但是使用 功能有以下优点:
1、当URL与当前路由匹配时,能自动匹配定义的“active”样式(这个你需要在路由配置中进行自定义linkActiveClass属性)
![70543ab96c73e56a0f4411c5eaeb0416.png](https://img-blog.csdnimg.cn/img_convert/70543ab96c73e56a0f4411c5eaeb0416.png)
2、会智能匹配路由为 hash 模式 还是 HTML5 history 模式,格式化成正确的URL格式。
3、当在 history 模式下,会阻止默认的单击操作行为,避免浏览器重新加载页面。
4、基于路由配置,构建相应的访问权限。
你可以像标签一样进行使用,只是URL相当组件的属性值而已:
![1180e7db7e563f0802d34e4b0c3c9bf9.png](https://img-blog.csdnimg.cn/img_convert/1180e7db7e563f0802d34e4b0c3c9bf9.png)
URL除了可以写成字符串的形式,你还可以写成对象的形式:
![f6d0cfe59473e4675bf41c949179d79c.png](https://img-blog.csdnimg.cn/img_convert/f6d0cfe59473e4675bf41c949179d79c.png)
虽然上面的两种写法是等价的,但是使用对象写法的形式,你能更方便的设置路由或URL传参:
1、Route parameters
![9cc7d2809abee2dec145fa20558faff3.png](https://img-blog.csdnimg.cn/img_convert/9cc7d2809abee2dec145fa20558faff3.png)
2、Query parameters
![f2255f693ede8e2636f130da507209c9.png](https://img-blog.csdnimg.cn/img_convert/f2255f693ede8e2636f130da507209c9.png)
二、JS编码的方式
如过你想通过JS的方式进行路由跳转,你可以在每个路由实例里,通过调用 this.$router 的相关方法。
1、push
此方法会创建一个对象(类似 组件传参的形式)并导航至定义的路由,此方法会将其保存到浏览器的历史里,我们可以使用返回功能,返回上一个URL。
![ad0997451378bbefe917f117c6e45c5f.png](https://img-blog.csdnimg.cn/img_convert/ad0997451378bbefe917f117c6e45c5f.png)
2、replace
此方法几乎与 push() 方法相同,不同之处,这里是替换当前浏览器的历史记录, push()是追加。
![63e058495a67e8b6369cad75b4d1a0a0.png](https://img-blog.csdnimg.cn/img_convert/63e058495a67e8b6369cad75b4d1a0a0.png)
3、go
你可以使用 go() 方法,通过整数(正数或负数都可以)传参向前或向后移动,访问浏览器的浏览历史。
![e18e94ed3ed3b9f17897ba1d0395bccc.png](https://img-blog.csdnimg.cn/img_convert/e18e94ed3ed3b9f17897ba1d0395bccc.png)
路由守卫(Navigation Guards)
正如其名,vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。有多种机会植入路由导航过程中:全局的, 单个路由独享的, 或者组件级的。
路由守护最常用的地方就是账户权限验证,不同级别的用户访问不同的页面和使用相应的功能。
一、全局守卫(Global Guards)
你可以通过以下方法,在所有的路由中启用对应的方法进行全局守卫,你可以为每个方法分别进行定义,并按照相应的注册顺序进行调用,除非进行取消,否则控制权将会一级一级的依次传导。
1、beforeEach
beforeEach:全局前置守卫。其作用就是在路由跳转之前执行,只要使用了beforeEach设置,注册的路由都会回调对应的方法,其方法传递了三个参数:to,from 和 next 。
![fdd4ea76d36488368877f683ee4ff15c.png](https://img-blog.csdnimg.cn/img_convert/fdd4ea76d36488368877f683ee4ff15c.png)
接下来解释下每个参数的意思:
“to”: 即将要进入的目标 路由对象;(这个对象中包含name,params,meta等属性)
"from": 当前导航正要离开的路由对象;(这个对象中包含name,params,meta等属性)
“next”: Function: 确保要调用 next 方法,否则钩子就不会被 resolved。这个当中还可以传一些参数,简单说明下:
- next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)
- next(false): 中断当前的导航。如果浏览器的 URL 改变了(可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址 —— 也就是说并不是单纯的中断,还会检查URL的变更以保证不会错误的进入到next路由
- next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。可传递的参数与router.push中选项一致
- next(error): (v2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调
2、beforeResolve
beforeResolve:全局解析守卫,区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用。即在 beforeEach 和 组件内beforeRouteEnter(稍后会介绍到) 之后,换个说法就是,这是阻止路由更改的最后机会。
![95e871500206aa909fdf9136b7ceee10.png](https://img-blog.csdnimg.cn/img_convert/95e871500206aa909fdf9136b7ceee10.png)
其参数和beforeEach的方法一致,这里就不过多介绍了。
3、afterEach
afterEach:全局后置守卫,和beforeEach相反,它是在路由跳转完成后触发,参数包括to,from没有了next,它发生在beforeEach和beforeResolve之后,beforeRouteEnter(组件内守卫,稍后会介绍)之前。
![acfa47f852fe426aca5952d1a6108421.png](https://img-blog.csdnimg.cn/img_convert/acfa47f852fe426aca5952d1a6108421.png)
二、路由独享的守卫
beforeEnter
可直接定义在路由配置上,和beforeEach方法参数、用法相同
![7e0d0f16ecede60110b9ae15094e6ef5.png](https://img-blog.csdnimg.cn/img_convert/7e0d0f16ecede60110b9ae15094e6ef5.png)
三、组件内的守卫(Per-route guards)
1、beforeRouteEnter
在渲染该组件的对应路由被确认前调用,用法和参数与beforeEach类似,next需要被主动调用注意:此时组件实例还未被创建,不能访问this。
![c4d4af06c9fb980e9429a5cb97809299.png](https://img-blog.csdnimg.cn/img_convert/c4d4af06c9fb980e9429a5cb97809299.png)
2、beforeRouteUpdate
在当前路由改变,并且该组件被复用时调用,可以通过this访问实例。
![8cb22bef9b25bc57217a06d9228f920b.png](https://img-blog.csdnimg.cn/img_convert/8cb22bef9b25bc57217a06d9228f920b.png)
3、beforeRouteLeave
导航离开该组件的对应路由时调用此方法,可以访问组件实例 this。
![4f2455d1918931b2da6738d3017b2b55.png](https://img-blog.csdnimg.cn/img_convert/4f2455d1918931b2da6738d3017b2b55.png)
守卫小节
说了这么多,我们来做个总结:
- 导航行为被触发,此时导航未被确认。
- 在失活的组件里调用离开守卫 beforeRouteLeave。
- 调用全局的 beforeEach 守卫。
- 在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
- 在路由配置里调用 beforeEnter。
- 解析异步路由组件(如果有)。
- 在被激活的组件里调用 beforeRouteEnter。
- 调用全局的 beforeResolve 守卫 (2.5+),标示解析阶段完成。
- 导航被确认。
- 调用全局的 afterEach 钩子。
- 非重用组件,开始组件实例的生命周期
- beforeCreate&created
- beforeMount&mounted
- 触发 DOM 更新。
- 用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数。
- 导航完成
![ce9edefa9c8c9b8625e36894ea5226cd.png](https://img-blog.csdnimg.cn/img_convert/ce9edefa9c8c9b8625e36894ea5226cd.png)
为了方便你理解路由执行顺序,建议你做个练习加深下理解,你可以创建个Route.js页面代码如下:
![070b855ab1d39eead4a0b2946b53e6a5.png](https://img-blog.csdnimg.cn/img_convert/070b855ab1d39eead4a0b2946b53e6a5.png)
接下来我们创建 user.vue 页面
![f82ea6196fa571bc78b38cde649fa26d.png](https://img-blog.csdnimg.cn/img_convert/f82ea6196fa571bc78b38cde649fa26d.png)
核心就是这两个页面,其它页面随意创建就可以,建议大家亲自做下尝试下。
练习:带权限验证路由的例子
最后,我们还是做个小练习,把前面学习的内容消化和理解下,我们来尝试做一个经常用到场景,就是用户登录场景,用户登录成功后,才能访问相应的页面,为了方便演示,我们创建一个模拟身份验证的服务,在真实的应用中,你需要调用服务端相应的接口服务用于验证.基于上一节我们创建的Vue项目,我们新建个auth.js文件。
src/auth.js
![7cec611b0713c30381d9487055fd5ed7.png](https://img-blog.csdnimg.cn/img_convert/7cec611b0713c30381d9487055fd5ed7.png)
此服务提供了一个login()方法,该方法检查用户输入的电子邮箱和密码信息,如果匹配则返回True,接下来我们创建一个登陆页面。
src/views/Login.vue
![1d14cf645861b66306727970c1b793fd.png](https://img-blog.csdnimg.cn/img_convert/1d14cf645861b66306727970c1b793fd.png)
最终完成后的效果如下图所示:
![d5c4f3b02ae7aadcb36f86204582aef8.png](https://img-blog.csdnimg.cn/img_convert/d5c4f3b02ae7aadcb36f86204582aef8.png)
从上述的代码,我们可以看出,如果用户登录成功,我们调用$router.push()方法,将用户导航至users路由页面。有了登录页面和权限验证服务,接下来我们需要保护相关需要授权才能看到页面,这里就用到了路由守卫。接下来我们来修改router.js,示例代码如下:
src/router.js
![78138e3592a031bc94167b617a9815f1.png](https://img-blog.csdnimg.cn/img_convert/78138e3592a031bc94167b617a9815f1.png)
从上述代码我们看出,首先我们导入了验证服务,对于我们要保护的路由,我们配置beforeEnter守卫,检验用户是否登录,如果用户未登录,将用户导向login路由。
接下来我们创建Users页面,示例代码如下:
views/Users.vue
![443b39912b700978eff210e70bc3402e.png](https://img-blog.csdnimg.cn/img_convert/443b39912b700978eff210e70bc3402e.png)
这里我们定义了两个路由守卫,这个页面只是通过路径传参更新页面内容。
接下来我们来创建一个游客界面,及未授权的用户访问的页面Home.vue。
views/Home.vue
![423c4dfe91920560af08f2abf52518af.png](https://img-blog.csdnimg.cn/img_convert/423c4dfe91920560af08f2abf52518af.png)
上述页面,如果用户未登录,会将用户导航至登录页面,好了,到这里,我们就完成了一个登录授权的路由守卫的例子。
小节
关于路由知识的分享就到这里,本篇文章我们一起学习导航组件和路由守卫的知识,并一起完成了相关的练习,在下一篇系列文章里,我们来一起学习下 Vuex State 状态管理,敬请期待。
vue基础相关文章
「vue基础」新手快速入门篇(一)
「vue基础」Vue相关构建工具和基础插件简介
「vue基础」手把手教你编写一个简单的 Vue 组件
「vue基础」深入学习如何编写 Vue 组件
「vue基础」一篇浅显易懂的 Vue 路由使用指南( Vue Router 上)