Vue中路由守卫的具体应用

目录

🔽 概述

1. 全局守卫——全局钩子函数

1.1 全局前置守卫——beforeEach

1.2 全局后置路由守卫

1.3 整合

2. 路由独享的守卫——路由独享的钩子函数

3.组件内的守卫——组件内的钩子函数

🔽 参考资料


Vue-Router导航(路由)守卫就是路由跳转前、中、后过程中的一些钩子函数,本文详细的介绍了Vue中路由守卫的具体使用——vue-router钩子函数实现路由守卫,具有一定的参考价值,对vue感兴趣的同学可以参考一下。

🔽 概述

何为路由守卫?路由守卫有点类似于ajax的请求拦截器,就是请求发送之前先给你拦截住做一些事情之后再去发送请求,同样这里的路由守卫意思差不多;简单理解为就是你在进路由之前,首先把你拦住,对你进行检查;这是不是有点中学门口的保安?进来之前拦住,有学生证就进,没有学生证就不让进;当然,路由守卫不仅仅只是在你进入之前拦住你,还有其他的钩子函数进行其他操作。

闲话:有的时候,需要通过路由来进行一些操作,比如,最常见的登录权限验证,当用户满足条件时,才让其进入导航,否则就取消跳转,并跳到登录页面让其登录。 为此有很多种方法可以植入路由的导航过程:全局的,单个路由独享的,或者组件级的。

路由守卫的作用:对路由进行权限控制

路由守卫的分类:全局守卫、独享守卫、组件内守卫

vue-router一共给我们提供了三大类钩子函数来实现路由守卫:

1、全局钩子函数(beforeEach、afterEach)  ——全局路由钩子

2、路由独享的钩子函数(beforeEnter) ——路由独享守卫

3、组件内钩子函数(beforeRouterEnter、beforeRouterUpdate、beforeRouterLeave)——组件内的守卫

首先我们先来看一下全局钩子函数:

1. 全局守卫——全局钩子函数

全局守卫,也称全局钩子函数、全局路由钩子

1.1 全局前置守卫——beforeEach

顾名思义,前置守卫主要是在你进行路由跳转之前根据你的状态去 进行一系列操作(全局前置是为在路由初始化以及跳转之前都会触发)

你可以使用router.beforeEach注册一个全局前置守卫(Each:每个,即在任意一个路由跳转的时候都会触发)

每个守卫方法接收三个参数:

to:Route:即将进入目标的路由对象

from:Route:当前导航正要离开的路由对象

next:function:一定要调用该方法来resolve这个钩子。执行效果依赖next方法的调用参数

(1). next():进行管道中的下一个钩子(to),即进入该路由。如果钩子执行完了,则导航状态就是confirmed(确认的)

(2). next(false):中断当前的导航,取消进入路由。如果浏览器的URL改变了(可能用户手动或者浏览器按后退按钮),那么地址会重置到from路由对应的地址。

(3). next('/")或者next( { path: '/' } ):跳转到一个新的地址。当前的导航被中断,然后进行下一个新的导航。你可以想next传递任意对象,且允许设置诸如replace:true、name:'home‘ 之类的选项以及任何用下router-link的 to prop或者router.push中的选项

确保next函数在任何给定的导航守卫中被严格调用一次,它可以出现多余一次,但是只能在所有的逻辑路径都不重叠的情况下,否则钩子永远都不会被解析或者错误。

1.1.1 使用

可以打印出from、to、next看他们究竟会保存那些信息

举例

import Vue from "vue";
import VueRouter from "vue-router";
import Home from "../views/Home.vue";
import About from "../views/About.vue";
import News from "../views/News.vue";
import Message from "../views/Message.vue";

Vue.use(VueRouter);

const routes = [
  {
    path: "/home",
    name: "Home",
    component: Home,
    children: [
      {
        path: "message", //此处不要写成:/message
        component: Message,
      },
    ],
  },

  {
    path: "/about",
    name: "aboutName",
    component: About,
    children: [
      {
        //通过children配置子级路由
        path: "news", //此处不要写成:/news
        component: News,
      },
    ],
  },
];

const router = new VueRouter({
  routes,
});

//全局前置路由守卫---初始化的时候被调用、每次路由切换的时候被调用
router.beforeEach((to, from, next) => {
  console.log(to); //这里是一个简单的例子 //即判断用户是否进入了需要鉴权的路由下(这里举例为news和message)
  if (to.path == "/home/message" || to.path === "/about/news") {
    //如果进入了,那就判断本地是否缓存了信息(这里模拟登录的token)
    if (localStorage.getItem("name") === "kaodigua") {
      next();
    }
  } else {
    //如果不是,则直接放行即可
    next();
  }
});

export default router;

上面这个例子有个不足之处是,当需要鉴权的路由很多的时候,那你需要一个一个的去判断?那大可不必,因此这里引入路由的另一属性,即meta,可以在每个路由中进行配置,一般用来标识具有标识性的属性,可以用来统一判断,具体如下:

Vue.use(VueRouter);

// 路由字典
const routes = [
  {
    path: "/home",
    name: "Home",
    children: [
      // 通过children配置子级路由
      {
        path: "message", //此处不要写成: /news
        component: MessageChannel,
        meta: {
          isAuth: true, //用于判断是否需要鉴权
        },
      },
    ],
  },
  {
    path: "/about",
    name: "/aboutName",
    component: About,
    children: [
      // 通过children配置子级路由
      {
        path: "news", // 此处不要写成:/news
        component: News,
        meta: {
          isAuth: false, // 表示不需要鉴权
        },
      },
    ],
  },
];

// 路由器对象
const router = new VueRouter({ routes });

//使用meta
router.beforeEach((to, from, next) => {
  console.log(to);
  if (to.meta.isAuth) { //判断是否需要鉴权
   //如果进入了,那就判断本地是否缓存了信息(这里模拟登录的token)
    if (localStorage.getItem("name") === "kaodigua") {
      next();
    }
  } else {
    // 如果不是,直接放行即可
    next();
  }
});

关于全局前置守卫——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 (window.localstorange.getItem("token")) {
    // 如果存在,则直接跳转到对应路由
     next();
  } else {
    // 如果不存在,则跳转到登录页
    next('/login');
  }
});

1.2 全局后置路由守卫

//全局后置路由守卫---初始化的时候被调用、每次路由切换之后被调用
router.afterEach((to, from) => {
  if (to.meta.title) {
    document.title = to.meta.title || '路由跳转举例'//修改网页的title
  }else{
    document.title = 'vue_test'
  }
})

关于全局后置守卫——afterEach

AfterEach和beforeEach一样都是属于全局守卫钩子,都是在main.js中进行调用;其中AfterEach比beforeEach少一个next参数;

to:即将进入的路由对象;
from:正要离开的路由对象;

afterEach()我们一般用来重置页面滚动条位置:假如我们有一个页面很长,滚动后其中的某个位置后跳转,这时新的页面的滚动条位置就会在上一个页面停留的位置;这个时候我们就可以利用afterEach进行重置:

//全局路由改变后的钩子
router.afterEach((to, from) => {
  //将滚动条恢复到最顶端
  window.scrollTo(0, 0);
})

1.3 整合

全局守卫

// 全局前置守卫---初始化时执行、每次路由切换前执行
router.beforeEach((to, from, next) => {
  console.log('beforeEach',to,from);
  if (to.meta.isAuth) {//判断当前路由是否需要进行权限控制
    //如果进入了,那就判断本地是否缓存了信息(这里模拟登录的token)
    if (localStorage.getItem("school") === "atguigu") {// 权限控制的具体规则
      next(); // 放行
    }else{
      alert('您暂无权限查看')
      // next({name:'guangyu'})
    }
  } else {
    next(); // 放行
  }
});
​
//全局后置守卫---初始化时执行、每次路由切换后执行
router.afterEach((to, from) => {
  console.log('afterEach',to,from);
  if (to.meta.title) {
    document.title = to.meta.title //修改网页的title
  }else{
    document.title = 'vue_test'
  }
})

2. 路由独享的守卫——路由独享的钩子函数

你可以在路由配置直接定义beforeEnter守卫,这些参数与全局前置守卫的方法参数是一样的

const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      beforeEnter: (to, from, next) => {
        // ...
      }
    }
  ]
})

关于路由独享守卫——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这个钩子,如果进入其他页面,是不触发的; 

3.组件内的守卫——组件内的钩子函数

最后,你可以在路由组件内直接定义一下路由导航守卫:

  • beforeRouterEnter
  • beforeRouterUpdate
  • beforeRouterLeave
const Foo = {
  template: `...`,
  beforeRouteEnter(to, from, next) {
    // 在渲染该组件的对应路由被 confirm 前调用
    // 不!能!获取组件实例 `this`
    // 因为当守卫执行前,组件实例还没被创建
  },
  beforeRouteUpdate(to, from, next) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 可以访问组件实例 `this`
  },
  beforeRouteLeave(to, from, next) {
    // 导航离开该组件的对应路由时调用
    // 可以访问组件实例 `this`
  },
};

关于组件内的守卫——beforeRouterEnter、beforeRouterUpdate、beforeRouterLeave

👉 
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,而beforeRouteUpdatebeforeRouteLeave都是可以访问到实例的,因为当这两个函数触发的时候实例都已经被创建了;

当调用组件内的钩子函数的时候,我们通常是在组件内部进行调用,举个例子:

​
<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) {
    window.document.title = "欢迎";
    next();
  },
  //路由修改时调用
  beforeRouteUpdate(to, from, next) {},
  //路由离开时调用
  beforeRouteLeave(to, from, next) {},
  data() {
    return {
      msg: "我是page1组件",
    };
  },
};
</script>

🔽 参考资料 

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Vue路由守卫用于在导航过程对路由进行拦截和控制访问权限。你可以使用全局守卫、路由独享守卫和组件内守卫三种类型的守卫。 1. 全局守卫:可以在路由配置文件(通常是`router/index.js`)定义全局的路由守卫,如`beforeEach`、`beforeResolve`和`afterEach`。例如: ```javascript import router from './router' router.beforeEach((to, from, next) => { // 在进入每个路由之前执行的逻辑 // 例如验证用户是否登录,检查权限等 // 如果要跳转到下一个路由,调用next()方法,否则调用next(false)取消导航 }) router.afterEach(() => { // 导航完成后的逻辑 }) ``` 2. 路由独享守卫:可以在某个具体路由配置定义独享的守卫,通过在路由配置添加`beforeEnter`属性来实现。例如: ```javascript const router = new VueRouter({ routes: [ { path: '/admin', component: Admin, beforeEnter: (to, from, next) => { // 在进入该路由前执行的逻辑 // 可以根据需求进行权限校验等操作 // 调用next()方法跳转到该路由,否则调用next(false)取消导航 } } ] }) ``` 3. 组件内守卫:可以在组件内部通过`beforeRouteEnter`、`beforeRouteUpdate`和`beforeRouteLeave`等守卫来定义路由钩子函数。例如: ```javascript export default { beforeRouteEnter(to, from, next) { // 在进入该路由前执行的逻辑 // 可以根据需求进行权限校验等操作 // 调用next()方法跳转到该路由,否则调用next(false)取消导航 }, beforeRouteUpdate(to, from, next) { // 路由更新时执行的逻辑 // 可以根据需求进行权限校验等操作 // 调用next()方法继续更新路由,否则调用next(false)取消导航 }, beforeRouteLeave(to, from, next) { // 在离开该路由前执行的逻辑 // 可以根据需求进行权限校验等操作 // 调用next()方法离开该路由,否则调用next(false)取消导航 } } ``` 以上就是在Vue使用路由守卫的方法,你可以根据具体的需求选择合适的守卫方式来实现路由的控制和拦截。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

儒雅的烤地瓜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值