接上一篇, 我们一起学习了 vue 路由的基本使用以及动态路由, 路由嵌套以及路由命名等知识, 今天我们一起来学习记录 vue-router 的钩子函数实现路由守卫;
何为路由守卫? 路由守卫有点类似于 Ajax 的请求拦截器, 就是请求发送之前先给你拦截住做一些事情之后再去发送请求, 同样这里的路由守卫意思差不多; 简单理解为就是你在进路由之前, 首先把你拦住, 对你进行检查; 这是不是有点中学门口的保安? 进来之前拦住, 有学生证就进, 没有学生证就不让进; 当然, 路由守卫不仅仅只是在你进入之前拦住你, 还有其他的钩子函数进行其他操作;
vue-router 一共给我们提供了三大类钩子函数来实现路由守卫:
1, 全局钩子函数 (beforeEach,afterEach)
2, 路由独享的钩子函数 (beforeEnter)
3, 组件内钩子函数 (beforeRouterEnter,beforeRouterUpdate,beforeRouterLeave)
首先我们先来看一下全局钩子函数:
全局钩子函数:
beforeEach:
beforeEach 一共接收三个参数, 分别是 to,from,next;to: 即将进入的路由对象; from: 正要离开的路由对象; next: 路由的控制参数;
next 一共有四种调用方式:
next(): 一切正常调用这个方法进入下一个钩子;
next(false): 取消路由导航, 这时的 url 显示的是正要离开的路由地址;
next('/login'): 当前路由被终止, 进入一个新的路由导航 (路由地址可以自由指定)
next(error): 路由导航终止并且错误会被传递到 router.onError() 注册过的回调中;
我们一般是用全局钩子来控制权限, 像什么进页面没有登录就跳登录页, 需要用户达到什么级别才能访问当前页面都是属于页面权限控制, 都是可以通过 beforeEach 钩子函数来实现:
- main.JS(全局钩子函数我们一般是在 main.JS 中进行书写):
- // 进入路由前方法勾子
- router.beforeEach((to, from, next) => {
- console.log(to, '前置第一个参数')
- console.log(from, '前置第二个参数')
- console.log(next, '前置第三个参数')
- /
to 目标路由
from 源路由
next 跳转到下一个路由
- */
- // 这里暂时用 local,storange 来简单模拟验证权限
- if (Windows.localstorange.getItem("token")) {
- // 如果存在, 则直接跳转到对应路由
- next();
- } else {
- // 如果不存在, 则跳转到登录页
- next('/login');
- }
- });
- AfterEach:
AfterEach 和 beforeEach 一样都是属于全局守卫钩子, 都是在 main.JS 中进行调用; 其中 AfterEach 比 beforeEach 少一个 next 参数;
to: 即将要进入的路由对象;
from: 正要离开的路由对象;
afterEach() 我们一般用来重置页面滚动条位置:
假如我们有一个页面很长, 滚动后其中的某个位置后跳转, 这时新的页面的滚动条位置就会在上一个页面停留的位置; 这个时候我们就可以利用 afterEach 进行重置:
- // 全局路由改变后钩子
- router.afterEach((to, from) => {
- // 将滚动条恢复到最顶端
- Windows.scrollTo(0, 0);
- })
路由独享的钩子函数:
beforeEneter:
路由独享顾名思义就是指定的路由才有这些钩子函数, 通常这类路由独享的钩子函数我们是在路由配置文件中进行配置, 只能设置改变前的钩子, 不能设置改变后的钩子
- const router=new VueRouter({
- routes
- });
- const routes=[
- {
- path:'/page1',
- component:page1,
- children: [
- {
- path: "phone",
- component: phone
- },
- {
- path: "computer",
- component: computer
- },
- ],
- // 路由独享的钩子函数
- beforeEnter:(to,from,next)=>{
- console.log(to);
- console.log(from);
- next(false);
- }
- },
上述代码理解为只有进入 / page1 才会触发 beforeEnter 这个钩子, 如果进入其他页面, 是不触发的;
组件内的钩子函数:
beforeRouteEnter(to,from,next):
在路由进入前调用, 因为此时的 vue 实例还没有创建, 所以 beforeEnter 是唯一一个不能使用 this 的钩子函数;
to: 即将要进入的路由对象;
from: 正要离开的路由对象;
next: 路由控制参数
beforeRouteUpdate(to,from,next):
在路由发生修改的时候进行调用, 比如我们上一篇文章讲到的动态路由传参, 这种情况我们的 beforeRouteUpdate 也是会被调用的;
to: 即将要进入的路由对象;
from: 正要离开的路由对象;
next: 路由控制参数;
beforeRouteLeave(to,from,next):
在路由离开该组件时调用;
to: 即将要进入的路由对象;
from: 正要离开的路由对象;
next: 路由控制参数
注意: beforeRouteEnter 因为触发的时候 vue 实例还没有创建, 所以这个钩子函数中不能使用 this, 而 beforeRouteUpdate 和 beforeRouteLeave 都是可以访问到实例的, 因为当这两个函数触发的时候实例都已经被创建了;
当调用组件内的钩子函数的时候, 我们通常是在组件内部进行调用, 举个例子:
- <template>
- <div>
- <h1 id="h1"> 主页 </h1>
- <p>
- <router-link to="/page1/phone"> 手机 </router-link>
- <router-link to="/page1/computer"> 电脑 </router-link>
- </p>
- <router-view></router-view>
- </div>
- </template>
- <script>
- export default {
- // 路由进入前调用
- beforeRouteEnter (to, from, next) {
- Windows.document.title = "欢迎";
- next();
- },
- // 路由修改时调用
- beforeRouteUpdate(to,from,next){
- },
- // 路由离开时调用
- beforeRouteLeave(to,from,next){
- },
- data () {
- return {
- msg: "我是 page1 组件"
- }
- },
- }
- </script>
image.PNG
来源: http://www.jianshu.com/p/6c308a31888d