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

2024-09-04 03:12

本文主要是介绍动态路由和路由导航守卫及其案例分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

为什么需要动态路由?

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

相关文章

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

动态规划---打家劫舍

题目: 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。 思路: 动态规划五部曲: 1.确定dp数组及含义 dp数组是一维数组,dp[i]代表

【区块链 + 人才服务】可信教育区块链治理系统 | FISCO BCOS应用案例

伴随着区块链技术的不断完善,其在教育信息化中的应用也在持续发展。利用区块链数据共识、不可篡改的特性, 将与教育相关的数据要素在区块链上进行存证确权,在确保数据可信的前提下,促进教育的公平、透明、开放,为教育教学质量提升赋能,实现教育数据的安全共享、高等教育体系的智慧治理。 可信教育区块链治理系统的顶层治理架构由教育部、高校、企业、学生等多方角色共同参与建设、维护,支撑教育资源共享、教学质量评估、

客户案例:安全海外中继助力知名家电企业化解海外通邮困境

1、客户背景 广东格兰仕集团有限公司(以下简称“格兰仕”),成立于1978年,是中国家电行业的领军企业之一。作为全球最大的微波炉生产基地,格兰仕拥有多项国际领先的家电制造技术,连续多年位列中国家电出口前列。格兰仕不仅注重业务的全球拓展,更重视业务流程的高效与顺畅,以确保在国际舞台上的竞争力。 2、需求痛点 随着格兰仕全球化战略的深入实施,其海外业务快速增长,电子邮件成为了关键的沟通工具。

【区块链 + 人才服务】区块链集成开发平台 | FISCO BCOS应用案例

随着区块链技术的快速发展,越来越多的企业开始将其应用于实际业务中。然而,区块链技术的专业性使得其集成开发成为一项挑战。针对此,广东中创智慧科技有限公司基于国产开源联盟链 FISCO BCOS 推出了区块链集成开发平台。该平台基于区块链技术,提供一套全面的区块链开发工具和开发环境,支持开发者快速开发和部署区块链应用。此外,该平台还可以提供一套全面的区块链开发教程和文档,帮助开发者快速上手区块链开发。

SWAP作物生长模型安装教程、数据制备、敏感性分析、气候变化影响、R模型敏感性分析与贝叶斯优化、Fortran源代码分析、气候数据降尺度与变化影响分析

查看原文>>>全流程SWAP农业模型数据制备、敏感性分析及气候变化影响实践技术应用 SWAP模型是由荷兰瓦赫宁根大学开发的先进农作物模型,它综合考虑了土壤-水分-大气以及植被间的相互作用;是一种描述作物生长过程的一种机理性作物生长模型。它不但运用Richard方程,使其能够精确的模拟土壤中水分的运动,而且耦合了WOFOST作物模型使作物的生长描述更为科学。 本文让更多的科研人员和农业工作者

MOLE 2.5 分析分子通道和孔隙

软件介绍 生物大分子通道和孔隙在生物学中发挥着重要作用,例如在分子识别和酶底物特异性方面。 我们介绍了一种名为 MOLE 2.5 的高级软件工具,该工具旨在分析分子通道和孔隙。 与其他可用软件工具的基准测试表明,MOLE 2.5 相比更快、更强大、功能更丰富。作为一项新功能,MOLE 2.5 可以估算已识别通道的物理化学性质。 软件下载 https://pan.quark.cn/s/57