动态路由和路由导航守卫及其案例分析

为什么需要动态路由?

动态路由其实用的不多,在实际开发中,如果遇到权限分配问题,比如对于一个公司人员的后台管理系统,那对不同成员的权限肯定不同,对于人事部,他们有权限进入成员表对人员的流动进行管理,对于技术部,他们有权上传任务进度来进行团队协作等等。对于不同人员,界面的渲染也不能相同。在有一些公司中可能会采用隐藏组件来实现权限的分配,但这样治标不治本:路由还是注册了,理论上只要知道路径,即使没有相应的组件来进入目标页面,也可以通过映射关系进入。这就会产生bug,所以有时会采用动态路由。

动态路由,顾名思义,就是在一定条件下才会注册路由,要不然根本不注册,脱离了路由就失去了映射关系,这样就不会出现bug了。

动态路由

其实动态路由核心就只有一个:addRoute方法,在这个方法中,可以传入一个对象,填入path,component,query等参数。

let isAdmin = true
if (isAdmin) {
router.addRoute({
path: "/admin",
component: () => import("@/Views/Admin.vue")
})
}//嵌套写法if (isAdmin){router.addRoute("home",{path:"/home/vip",component: ()=> import("")})}

以上只是模拟一下权限的分配,真实情况下权限的分配是根据服务器传回来的响应来决定的。

当isAdmin为true时,说明权限为管理员,这时我们就给其注册路由,创建Admin.vue与"/admin"的映射关系。

当然,想要移除也是同理,使用removeRoute方法,传入路由的name。

路由导航守卫⭐

了解路由导航守卫前,我们只要了解一个业务就能很好理解:

对于刚进入淘宝的游客,他可以浏览商品但是当购买商品时不会跳转到购买界面而是会重定向到登录/注册界面,只有当注册/登录完成后服务器返回用户特定的token后才会允许他进入购买界面,生成token那是后端的逻辑,暂且不论。对于重定向,路由导航守卫起到很大作用:导航守卫会在用户每次前往某个界面前先检查一下用户是否满足条件,如果不满足条件就会执行回调函数,一般是重定向,在满足条件后可以正常进入。

视频分析 

接下来,我们结合一个视频案例来说明路由导航守卫最终的效果

2024-09-03 22-34-47

代码分析

在这篇文章仅仅展示路由导航守卫用到的代码,关于其他的代码可以翻阅上篇文章。

App.vue

<template><div class="app"><div class="main-nav"><!-- <router-link to="/home" replace>首页</router-link>  replace 替换路径,不会记录历史路径--> <!-- <router-link to="/home" active-class="link-class">首页</router-link> active-class指定选中的元素附带的className --><ul class="nav-bar"><li @click="homeLiClick">首页</li><li @click="aboutLiClick">关于</li><li @click="userLiClick">用户</li></ul></div><router-view></router-view> </div><!-- 编程式跳转页面 --></template><script setup>
import { useRouter } from 'vue-router';
const router = useRouter()function homeLiClick(){router.push({path:"/home",query:{}})
}
function aboutLiClick(){router.push({path:"/about",query:{name:"Lisman",age:"18",sex:"male"}})
}
function userLiClick(){router.push({path:"/user",query:{name:"Lisman",password:"123456"}})
}</script><style lang="less" scoped>
.main-nav {.nav-bar{list-style-type: none;display: flex;margin: 0;padding: 0;text-align: center;height: 44px;width: 100%;line-height: 44px;li{flex: 1;background-color: #454545;color: whitesmoke;font-size: 14px;font-weight: bold;cursor: pointer;}}
}</style>

Login.vue

<template><div class="login"><div class="container"><div class="header"><span>Admin Login</span></div><div class="content"><div class="login-content"><label for="username">username <input type="text" name="username"></label><label for="password">password <input type="text" name="password"></label><button @click="loginBtnClick">登录</button></div></div></div></div>
</template><script setup>
import { useRouter } from 'vue-router';
const router = useRouter()
function loginBtnClick(){window.localStorage.setItem("token","12234FFASSD")router.push({path:"/user",query:{name:"Lisman",password:"123456"}})
}
</script><style lang="less" scoped>
.login{height: 1000px;background-color: #c9c9c9;position: relative;.container{height: 400px;width: 50%;background-color: #fff;position: absolute;top:200px;left:25%;border-radius: 10px;.header{width: 80%;margin: 0 auto;height: 100px;text-align: center;line-height: 100px;span{font-weight: bold;font-size: 30px;padding-bottom: 3px;border-bottom: 2px solid black;}}.content{height: 255px;background-color: aquamarine;width: 75%;margin: 0 auto;border-radius: 10px;.login-content{width: 75%;height: 100px;margin: 0 auto;padding-top: 30px;position: relative;label{display: block;margin-bottom: 20px;margin-top: 30px;margin-left: 100px;}button{position: absolute;top: 170px;left: 340px;}}}}
}
</style>

User.vue

<template><div class="user"><div class="container"><div class="header"><span>User Info</span></div><div class="content"><div class="user-info"><h2 class="username">Username : {{ $route.query.name }}</h2><h2 class="password">Password : {{ $route.query.password }}</h2><button @click="logoutBtnClick">退出登录</button></div></div></div></div>
</template><script setup>
import { useRouter } from 'vue-router';const router = useRouter()function logoutBtnClick(){window.localStorage.removeItem("token")router.push("/home")
}
</script><style lang="less" scoped>
.user{height: 1000px;background-color: #c9c9c9;position: relative;.container{height: 400px;width: 50%;background-color: #fff;position: absolute;top:200px;left:25%;border-radius: 10px;.header{width: 80%;margin: 0 auto;height: 100px;text-align: center;line-height: 100px;span{font-weight: bold;font-size: 30px;padding-bottom: 3px;border-bottom: 2px solid black;}}.content{height: 255px;background-color: aquamarine;width: 75%;margin: 0 auto;border-radius: 10px;.user-info{width: 75%;height: 100px;margin: 0 auto;padding-top: 30px;position: relative;text-align: center;h2{padding-top: 20px;}}}}
}
</style>

index.js

import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router'//导入组件
// import Home from '@/Views/Home.vue'
// import About from '@/Views/About.vue'//以下为路由懒加载,import导入可以做到分包处理,webpackChunkName可以给包指定名字
// const Home = import(/* webpackChunkName: 'Home' */"../Views/Home.vue")
// const About = import(/* webpackChunkName: 'About' */"../Views/About.vue")//创建路由:映射关系
const router = createRouter({//选择模式(Hash)// history: createWebHashHistory(),history: createWebHashHistory(),routes: [{path: "/home",component: () => import("../Views/Home.vue"),//嵌套路由children: [{path: "recommend",//相当于/home/recommendcomponent: () => import("../Views/Recommend.vue")},{path: "ranking",component: () => import("../Views/Ranking.vue")},{path: "",redirect: "/home/recommend"}]},{ path: "/about", component: () => import("../Views/About.vue") },{ path: "/", redirect: "/home" },{ path: "/:pathMatch(.*)", component: () => import("../Views/NotFound.vue") },{ path: "/login", component: () => import("@/Views/Login.vue") },{ path: "/user", component: () => import("@/Views/User.vue") }]
})// let isAdmin = true
// if (isAdmin) {
//   router.addRoute({
//     path: "/admin",
//     component: () => import("@/Views/Admin.vue")
//   })
// }//嵌套写法
// if (isAdmin){
//   router.addRoute("home",{
//     path:"/home/vip",
//     component: ()=> import("")
//   })
// }//路由守卫,每次跳转都会执行回调
router.beforeEach((to, from) => {const token = window.localStorage.getItem("token")if (to.path === "/user" && !token) {return "/login"}
})//导出路由
export default router

框图分析 

以下为图例:

其实有关路由导航守卫的只要一段代码,其他部分主要是界面和token的获取和设置。

router.beforeEach((to, from) => {const token = window.localStorage.getItem("token")if (to.path === "/user" && !token) {return "/login"}
})

beforeEach()方法会在进入每个路径前激活它的回调函数,它拥有两个参数:to,from,to为目标路由,from为原来的路由,我们首先检查一下用户是否拥有token,判断目标路径是否为/user,如果没有token,那么就满足条件而重定向到/login。如果拥有token,那么就不满足条件,返回undefined,在beforeEach中如果返回undefined那就不做操作,该去哪去哪,守卫不会作用。

当然守卫不只beforeEach一种,不同的守卫应结合实际开发情况来使用,关于其他的守卫文档我放在下面了:

https://router.vuejs.org/zh/guide/advanced/navigation-guards.html

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PHP8、ThinkPHP8框架中间的应用教程详解

前言 虽然PHP的落幕的话题一直不绝&#xff0c;但是实际在WEB端项目中PHP占有率达到了70%以上&#xff0c;一直在WEB一枝独秀&#xff0c;它以快速、高效的开发闻名&#xff0c;出圈了几十年&#xff0c;等待只是下一次的涅槃。而经过PHP8、PHP9的演变发展&#xff0c;PHP逐渐…

【Linux网络编程】协议|OSI模型|TCP/IP模型|局域网通信|跨网络通信|地址管理|流程图

目录 ​编辑 一&#xff0c;协议 协议分层 二&#xff0c;OSI七层模型 三&#xff0c;TCP/IP五层&#xff08;或四层&#xff09;模型 TCP/IP各个层次一些名词解释 为什么要有TCP/IP协议 TCP/IP协议栈与操作系统的宏观关系示意图 四&#xff0c;网络传输基本流程 局…

【书生大模型实战营】MindSearch CPU-only 版部署

MindSearch CPU-only 版部署 MindSearch CPU-only 版部署任务步骤 MindSearch CPU-only 版部署 任务 将 MindSearch 部署到 HuggingFace 并美化 Gradio 的界面&#xff0c;并提供截图和 Hugging Face 的Space的链接。 步骤 按照官方教程&#xff0c;实现在网页上打开MindSe…

llama_factory Qlora微调异常 No package metadata was found for The ‘autoawq‘

importlib.metadata.PackageNotFoundError: No package metadata was found for The ‘autoawq’ distribution was not found and is required by this application. To fix: pip install autoawq 其实问题比较简单 直接安装autoawq 即可 但是对应会有版本问题&#xff1a; 查…

Python自适应光学模态星形小波分析和像差算法

&#x1f3af;要点 &#x1f3af;星形小波分析像差测量 | &#x1f3af;对比傅里叶和小波分析 | &#x1f3af;定义多尺度图像质量度量&#xff0c;矩阵数据 | &#x1f3af;像差校正算法 | &#x1f3af;受激发射损耗显微镜布局 | &#x1f3af;干涉仪分支校准&#xff0c;求…

【unity实战】使用新版输入系统Input System+Rigidbody实现第三人称人物控制器(附项目源码)

最终效果 前言 使用CharacterController实现3d角色控制器&#xff0c;之前已经做过很多了&#xff1a; 【unity小技巧】unity最完美的CharacterController 3d角色控制器&#xff0c;实现移动、跳跃、下蹲、奔跑、上下坡、物理碰撞效果&#xff0c;复制粘贴即用 【unity实战】C…

快速入门Go:Go + gin + MongoDB

Go 进阶:Go + gin + MongDB 极速搭建EcommerceSys电商系统 前言 本章节适合有一定基础的 Golang 初学者,通过简单的项目实践来加深对 Golang 的基本语法和 Web 开发的理解。 本文章持续更新中,请关注… 项目结构 项目流程图 技术栈(待补充)项目结构项目路由 (待补充) …

DataWhale AI夏令营-《李宏毅深度学习教程》笔记-task3

DataWhale AI夏令营-《李宏毅深度学习教程》笔记-task2 第五章 循环神经网络5.1 独热编码5.2 RNN架构5.3 其他RNN5.3.1 Elman 网络 &Jordan 网络5.3.2 双向循环神经网络 第五章 循环神经网络 循环神经网络RNN&#xff0c;RNN在处理序列数据和时间依赖性强的问题上具有独特…

51单片机——实时时钟

1、DS1302介绍 DS1302是由美国DALLAS公司推出的具有涓细电流充电能力的低功耗实时时钟芯片。它可以对年、月、日、周、时、分、秒进行计时&#xff0c;且具有闰年补偿等多种功能 RTC(Real Time Clock)&#xff1a;实时时钟&#xff0c;是一种集成电路&#xff0c;通常称为时钟…

机器学习项目——基于机器学习(RNN LSTM 高斯拟合 MLP)的锂离子电池剩余寿命预测方法研究(代码/论文)

完整的论文代码见文章末尾 以下为核心内容和部分结果 摘要 机器学习方法在电池寿命预测中的应用主要包括监督学习、无监督学习和强化学习等。监督学习方法通过构建回归模型或分类模型&#xff0c;直接预测电池的剩余寿命或健康状态。无监督学习方法则通过聚类分析和降维技术&…

VS-E5PH3006L-N3 600V 30A 高效低损耗整流器 二极管 电动 / 混动汽车电池充电的可靠之选

VS-E5PH3006L-N3参数特性&#xff1a; 反向电压&#xff08;VR&#xff09;&#xff1a;600V&#xff0c;这表示该整流器在电路中能承受的最大反向电压为 600 伏特&#xff0c;超过此电压可能会导致器件损坏。平均整流电流&#xff08;IF (AV)&#xff09;&#xff1a;30A&…

【系统架构设计】嵌入式系统设计(2)

【系统架构设计】嵌入式系统设计&#xff08;2&#xff09; 嵌入式网络系统嵌入式 Internet 的接入方式嵌入式 TCP/IP 协议栈 嵌入式数据库管理系统数据的一致性高效的事务处理数据的安全性 实时系统与嵌入式操作系统对实时系统划分根据实时性的强弱根据对错失时限的容忍程度或…

Linux学习-虚拟化平台安装和使用

注&#xff1a;系统使用Rock8.6 下载链接 通过百度网盘分享的文件&#xff1a;cirros.qcow2&#xff0c;node_base.xml等2个文件 链接&#xff1a;https://pan.baidu.com/s/1hupGQsMjrXMgngCy3lQLhw?pwdhlr6 提取码&#xff1a;hlr6[rootharbor ~]# cat /etc/redhat-releas…

《Class-Agnostic Counting》CVPR2018

概述 摘要&#xff1a;这篇论文提出了一种用于对象计数的模型&#xff0c;该模型能够计算任何类别的对象&#xff0c;而不需要针对特定对象类别进行设计。作者将计数问题表述为一个匹配问题&#xff0c;利用图像中自然存在的自相似性属性。论文的贡献包括&#xff1a;提出了一…

软件工程知识点总结(1):软件工程概述

1 什么是软件&#xff1f; 定义&#xff1a;计算机系统中的程序及其文档。 ——程序是计算机任务的处理对象和处理规模的描述&#xff1b; ——文档是为了便于了解程序所需要的阐明性资料。 2 软件的特点&#xff1f; 软件是无形的&#xff0c;不可见的逻辑实体 ——它的正确与…

人到中年,越发明白,随缘是成年人之间最好的社交状态

​时光荏苒&#xff0c;转眼间&#xff0c;我们已从青涩少年步入沉稳中年。 在这个阶段&#xff0c;我们经历了职场的起起落落&#xff0c;家庭的悲欢离合&#xff0c;也见证了身边人的种种变化。 正如屠格涅夫所言&#xff1a;“凡事只要看得淡些&#xff0c;就没有什么可忧…

C程序设计——指针杂谈0

变量和常量讲的差不多了&#xff0c;这里先把指针再深入理解一下&#xff0c;如果你是C语言初学者&#xff0c;本节可能看不太懂&#xff0c;没关系可以以后再看。 变量 当定义变量的时候&#xff0c;本质是在内存中分配了一段空间&#xff0c;这段空间的大小与变量的类型相关…

Hackme靶机通关攻略

1.首先注册用户&#xff0c;登录 2.登录后&#xff0c;显示让我们查找自己喜欢的书&#xff0c;我们直接单击search&#xff0c;会列出很多书 3.随便选择一本书进行查询&#xff0c;与此同时进行抓包 4.放到重放器中&#xff0c;将数据改为1*&#xff0c;将数据包另存为1.txt&a…

Python pip 更换镜像源

文章目录 1 概述1.1 默认镜像&#xff0c;速度慢&#xff0c;易报错1.2 常用国内镜像源 2 更改镜像源2.1 临时更改2.2 永久更改2.2.1 查看配置源及配置文件2.2.2 编辑 pip.ini2.2.3 配置后的效果 1 概述 1.1 默认镜像&#xff0c;速度慢&#xff0c;易报错 默认镜像&#xff…

Win32设备I/O详解

Windows设备 在Windows平台下&#xff0c;设备被定义为能够与之进行通信的任何东西。最常见的 I/O 设备包括&#xff1a;文件、文件流、目录、物理磁盘、卷、控制台缓冲区、磁带驱动器、通信资源、mailslot 和管道等。 平常我们使用的文件&#xff0c;目录都可以称之为设备。…