Vue中路由守卫的具体应用

news2024/12/24 3:40:47

目录

🔽 概述

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>

🔽 参考资料 

  • 详解vue-router导航守卫
  • vue的路由守卫和keep-alive后生命周期详解
  • 快速理解Vue路由导航守卫

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/95666.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

卫龙上市酿成资本惨剧:CPE损失上亿美元 高瓴浮亏5000万美元

雷帝网 雷建平 12月16日本是年度最受期待的新消费企业上市&#xff0c;却酿成资本惨剧。“辣条一哥”卫龙&#xff08;股票代码为&#xff1a;“09985”&#xff09;昨日在港交所上市&#xff0c;发行价为10.56港元&#xff0c;募资净额为8.99亿港元&#xff1b;卫龙食品首日开…

大数据中的数据安全

数据安全体系全貌 在数据仓库平台中&#xff0c;对应数据的请求必须严格尊属数据安全体系 数据使用安全 数据安全 认证 授权 认证主要是对用户的身份确认&#xff0c;比如最简单的用户的登录需要账户和密码&#xff1b;像你登录Mysql需要输出用户名和密码。比如大数据中使用…

爱科赛博冲刺科创板:拟募资3.8亿 陕西集成电路与达晨是股东

雷递网 雷建平 12月16日西安爱科赛博电气股份有限公司&#xff08;简称&#xff1a;“爱科赛博”&#xff09;日前递交招股书&#xff0c;准备在科创板上市。爱科赛博计划募资3.8亿。其中&#xff0c;1.2亿用于西安爱科赛博电气股份有限公司精密特种电源产业化建设项目&#xf…

2022.12.5-12.11 AI行业周刊(第127期):一起做时间的朋友

最近沸沸扬扬的就是核酸疫情的事情&#xff0c;突然之间&#xff0c;一下子全国都放开了&#xff0c;很不适应。 大宝在上幼儿园中班&#xff0c;上上个星期&#xff0c;学校的政策&#xff0c;还是没有核酸证明不得入校。 而上周末发的通知&#xff0c;已经是不得在外做核酸…

AIGC音乐生成#riff + diffusion 以生成频谱图图像来转换为音乐 | 无界日报 第2期

小杜无界日报第2期&#xff0c;本期头条 - stable diffusion 微调模型 riff diffusion 以生成频谱图图像来转换为音乐。无界日报2022.12.16第02期- 头条 -riff diffusion#AIGC# #工具#riff diffusion 是 stable diffusion 的微调模型&#xff0c;以生成频谱图图像来转换为音…

(文章复现)8.基于共享储能电站的工业用户日前优化经济调度

目录 复现文章&#xff1a; 摘要&#xff1a; 部分程序&#xff1a; 输出结果&#xff1a; 15r 复现文章&#xff1a; 基于共享储能电站的工业用户日前优化经济调度——李淋&#xff08;电力建设2020&#xff09; 摘要&#xff1a; 文章提出一种基于共享储能电站的工业…

【计算机网络】:2-物理层

物理层 物理层考虑的是怎样才能在各种计算机的传输媒体上传输数据比特流&#xff0c;主要涉及到的领域包括信号传播、电信系统等&#xff0c;与计算机软件相关较少 1.物理层介绍 物理层为数据链路层屏蔽了各种传输媒体的差异&#xff0c;使数据链路层 只需要考虑本层 的的协…

《Linux内核源码分析》课程笔记

《Linux内核源码分析》课程笔记漏洞安全与虚拟内存CPU缓存技术malloc系统调用中断锁与IPC机制MMU内存页回收内核设备驱动程序内核启动流程这个课好烂&#xff0c;就是打广告用的。出现的老师的英语听着难受。 漏洞安全与虚拟内存 CPU架构&#xff1a;1、X86架构&#xff0c;采…

绿盟SecXOps安全智能分析技术白皮书

数据共享 定义内涵 数据共享 是指在多个用户或多个程序之间遵循一定规则共同享用数据&#xff0c;并进行各种操作、运算和分析的一种技术。数据共享包括数据发布、接口、交换等内容。 技术背景 随着数字经济成为拉动全球经济增长的新引擎&#xff0c;大数据成为经济中重要的…

微服务框架 SpringCloud微服务架构 多级缓存 48 多级缓存 48.7 Redis 缓存预热

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式&#xff0c;系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 多级缓存 文章目录微服务框架多级缓存48 多级缓存48.7 Redis 缓存预热48.7.1 添加Redis 缓存的需求48.7.2 冷启动和缓存预热48.7.3 缓存预热…

高通平台开发系列讲解(DSI篇)DSI函数的内部逻辑

文章目录 一、dsi_start_data_call函数二、dsi_get_pkt_stats函数三、dsi_stop_data_call函数四、回调流程沉淀、分享、成长,让自己和他人都能有所收获!😄 📢DSI层最上层函数位于dsi_netctrl.c中,该.c位于apps_proc/data/dsi_netctrl目录中,现对部分主要函数的调用流程进…

大数据工程师的“卿卿日常”

大数据工程师在日常生活中做什么&#xff1f; 长按关注《Java学研大本营》&#xff0c;加入读者群&#xff0c;分享更多精彩 扫码关注《Java学研大本营》&#xff0c;加入读者群&#xff0c;分享更多精彩 什么是数据工程&#xff1f; 数据工程是当今世界最关键和最基础的技能…

25岁,一个汽修工人转行 Python 的真实事迹!

前言 我遇到一个汽修工人&#xff0c;他没有事喜欢上网&#xff0c;看新闻&#xff0c;对于编程很有兴趣&#xff0c;也想过转行&#xff0c;但是不知道学习什么好. 如何知道 Python. 我和这位朋友的家很近&#xff0c;在过年的时候&#xff0c;我们聊过 (20 出头), 我了解他是…

在vue中,为什么不能用index作为key?

啊&#xff1f;不是吧&#xff0c;在vue中&#xff0c;不能使用index作为key呢&#xff1f;使用index作为key又好理解又方便&#xff0c;为什么不能使用呢&#xff1f;看文章就知道啦~. 一、key的作用是什么&#xff1f; key的作用众所周知&#xff0c;看一个demo就知道&…

【FFmpeg视频播放器开发】解封装解码流程、常用API和结构体简介(一)

一、前言 在正式编写 FFmpeg 播放器前&#xff0c;我们需要先简单了解下所要用到的 FFmpeg 库、播放与解码流程、函数和相关结构体。 二、FFmpeg 库简介 库介绍avcodec音视频编解码核心库avformat音视频容器格式的封装和解析avutil核心工具库swscal图像格式转换的模块swresa…

零基础如何学好Python?Python有哪些必须学的知识?

跟几个IT界的大佬提起Python&#xff0c;他们说零基础学好Python很简单&#xff0c;Python进阶需要花费些气力。那么零基础如何学好Python&#xff1f;Python有哪些必须学的知识&#xff1f;学习的策略技巧有哪些&#xff1f;今天小编整理的这篇文章将会给你启发。 Python上手…

vulnhub靶机DriftingBlue6

靶机下载地址DriftingBlues: 6 ~ VulnHub kali ip&#xff1a;192.168.174.128 靶机ip&#xff1a; 192.168.174.140 首先进行ip地址发现 进行端口扫描 这里进行目录扫描&#xff0c;我习惯性使用Linux里面的gobuster和Windows上的dirsearch一起进行扫描。 python dirsearc…

Linux | 常见指令和常用热键

啊我摔倒了..有没有人扶我起来学习.... &#x1f471;个人主页&#xff1a;《CGod的个人主页》\color{Darkorange}{《CGod的个人主页》}《CGod的个人主页》交个朋友叭~ &#x1f492;个人社区&#xff1a;《编程成神技术交流社区》\color{Darkorange}{《编程成神技术交流社区》…

升级Linux服务器你必须要知道的事

服务器安全是每个系统管理员的头等大事。除了拥有第三方安全工具&#xff08;如防火墙&#xff0c;DDoS保护等&#xff09;外&#xff0c;使生产服务器上的所有代码保持最新也是极为重要的。 当您的应用程序投入生产时&#xff0c;升级它的风险更大。如果您的服务器由Linux驱动…

超级简单基于nodejs电商管理系统的设计与实现.zip(论文+源码+ppt文档+视频录制)

相关资料下载地址&#xff1a;请点击下载》》》 该商城平台整体上实现了商品管理模块、订单交易模块,购物车模块、商品列表股那里模块、用户模块模块。在这些功能模块独立运行和相互配合下形成了一个电商商城系统。在商城实现的技术架构方面,该商城采用nodejs作为商城后台的底…