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

为什么需要动态路由?

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

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

相关文章

云计算实训41——部署project_exam_system项目(续)

# 创建脚本&#xff0c;可以在java环境中运行任何的jar包或者war包#!/bin/bash/usr/local/jdk/bin/java -jar /java/src/*.?ar一、思路分析 &#xff08;1&#xff09;nginx 1、下载镜像&#xff0c;将本地的dist项目的目录挂载在容器的/usr/share/nginx/html/ 2、启动容器 …

性能工具之 JMeter ajax 简单登录案例实战

文章目录 一、前言二、前置工作三、登陆密码分析四、JMeter脚本开发四、登陆性能分析五、小结 一、前言 想起论语中的 “学而时习之不亦说乎” &#xff0c;也想找个开源项目实战一把&#xff0c;下面用一个开源ERP系统中的登陆做今天的实战。 二、前置工作 开源ERP项目地址…

getLocation:fail, the permission value is offline verifying

getLocation:fail, the permission value is offline verifying 后端会根据appid和secret生成 签名&#xff0c;前端wx配置时一定用appid来验证签名的正确 本次错误为配置初始化失败&#xff1a;前端与后端的appId不一致&#xff0c;我的失误也

IP 协议详解

一、认识 IP 地址与网络层的职责 网络层是OSI七层模型中的第三层&#xff0c;也是TCP/IP四层模型中的网络接入层。在这一层&#xff0c;数据包被封装并加上IP层的头部信息&#xff0c;以便在网络之间传输。网络层的主要功能包括路由选择、分段与重组、拥塞控制以及IP地址管理等…

stm32的内部时钟源 | RC震荡电路

文章目录 前言学习了解 前言 了解到 内部高速RC振荡器&#xff08;HSI&#xff09;就是RC震荡器实现的&#xff0c;故想对RC震荡做些了解与分析。 学习了解 【不需要晶振&#xff0c;也可产生时钟脉冲&#xff01;RC振荡器的工作原理&#xff0c;维恩电桥振荡器&#xff01;…

Mental-LLM——通过在线文本数据利用大型语言模型进行心理健康预测

概述 源码地址&#xff1a;https://github.com/neuhai/Mental-LLM.git 论文地址&#xff1a;https://arxiv.org/abs/2307.14385 在一项关于哪些法律硕士适合精神健康护理的研究中&#xff0c;对以下五种法律硕士进行了比较 羊驼-7b。羊驼-LoRA。FLAN-T5-XXLGPT-3.5GPT-4. 作…

AT+MQTT指令连接华为云实现数据上传

1 准备工作 硬件设备模块&#xff1a;ESP-01-S 固件烧录工具&#xff1a;ESP8266下载器 串口调试工具&#xff1a;VOFA参考文章&#xff1a;stm32AT指令ESP8266接入华为云物联网平台并完成属性上报与下发的命令处理 2 固件更新 2.1 为什么要重新安装固件 由于ESP-01-S模块出…

快速入门Go:Go + gin + MongoDB

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

带你0到1之QT编程:三、打地基QMap的高效用法

此为QT编程的第三谈&#xff01;关注我&#xff0c;带你快速学习QT编程的学习路线&#xff01; 每一篇的技术点都是很很重要&#xff01;很重要&#xff01;很重要&#xff01;但不冗余&#xff01; 我们通常采取总-分-总和生活化的讲解方式来阐述一个知识点&#xff01; 码…

KEYSIGHT U2020 X系列 USB峰值和均值功率传感器

​ _是德(KEYSIGHT) _ U2020 X系列 USB峰值和均值功率传感器 苏州新利通仪器仪表 U2020 X 系列功率传感器得到 Keysight BenchVue 软件的支持。使用 BenchVue 软件&#xff0c;您无需编程便可轻松控制功率计记录数据&#xff0c;并以各种形式显示测量结果。 只需将传感器…

计算机岗位(面试)

计算机岗位&#xff08;面试&#xff09; 计算机主要有哪几部分构成&#xff1f;计算机组成原理的内容&#xff1f; 计算机主要由‌硬件和软件‌两大部分构成。‌硬件部分包括五大基本组件&#xff1a;‌‌运算器、‌控制器、‌存储器、‌输入设备和输出设备‌‌。‌具体来说&a…

仿华为车机UI--图标从Workspace拖动到Hotseat同时保留图标在原来位置

基于Android13 Launcher3,原生系统如果把图标从Workspace拖动到Hotseat里则Workspace就没有了&#xff0c;需求是执行拖拽动作后&#xff0c;图标同时保留在原位置。 实现效果如下&#xff1a; 实现思路&#xff1a; 1.如果在workspace中拖动&#xff0c;则保留原来“改变图标…

【开源免费】基于SpringBoot+Vue.JS高校校园招聘服务系统(JAVA毕业设计)

本文项目编号 T 010 &#xff0c;文末自助获取源码 \color{red}{T010&#xff0c;文末自助获取源码} T010&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…

渗透测试靶机---- DC系列 DC-4

渗透测试靶机---- DC系列 DC-4 开启靶机&#xff0c;登录页面&#xff0c;平平无奇 扫描ip 端口&#xff0c;服务等信息 访问80 登录窗&#xff01;&#xff01;&#xff01; 这里说明了admin信息&#xff0c;那么就直接爆破这个admin的密码 密码&#xff1a;happy 登录成功 在…

Mysql之存储引擎概述

文章目录 存储引擎MySQL体系结构存储引擎特点InnoDBMyISAMMemory总结 存储引擎选择 存储引擎 MySQL体系结构 连接层&#xff1a;最上层是一些客户端和链接服务&#xff0c;主要完成一些类似于连接处理、授权认证、及相关的安全方案。服务器也会为安全接入的每个客户端验证它所…

Rust多线程编程概述

【图书介绍】《Rust编程与项目实战》-CSDN博客 《Rust编程与项目实战》(朱文伟&#xff0c;李建英)【摘要 书评 试读】- 京东图书 (jd.com) Rust到底值不值得学&#xff0c;之一 -CSDN博客 Rust到底值不值得学&#xff0c;之二-CSDN博客 12.2.1 线程的基本概念 线程&…

随手记:小程序体积超出2M包大小如何优化

小程序的包体积限制是2M&#xff0c;超出包大小如何优化 先简单列出&#xff0c;最近比较忙&#xff0c;后续优化明细&#xff0c;有着急的先留言踢我 1.分包 留几个主要的页面体积小的&#xff0c;剩下的在page.json中拆到subpackages中&#xff0c;简单举个例子 "page…

58、Python之函数高级:不定参数的函数,写出更加通用的装饰器

引言 上一篇文章中&#xff0c;我们见到引入了Python中的装饰器&#xff0c;通过一个简单的案例实现了一个初步的装饰器&#xff0c;但是&#xff0c;这个装饰器其实是有些缺陷。这一篇文章中&#xff0c;我们对上一篇文章中的装饰器进行一个优化升级&#xff0c;从而写出更加…

【王树森】RNN模型与NLP应用(5/9):多层RNN、双向RNN、预训练(个人向笔记)

Stacked RNN&#xff08;多层RNN&#xff09; 1. 原理 多个全连接层可以堆叠&#xff0c;多个卷积层也可以堆叠。同理&#xff1a;RNN也可以堆叠形成多层RNN。 如下图所示&#xff1a;对于每一个时刻的输出 h t h_t ht​&#xff0c;它既会作为下一个时刻的输入&#xff0c;…

ElasticSearch学习笔记(三)RestClient操作文档、DSL查询文档、搜索结果排序

文章目录 前言5 RestClient操作文档5.4 删除文档5.4 修改文档5.5 批量导入文档 6 DSL查询文档6.1 准备工作6.2 全文检索查询6.3 精准查询6.4 地理坐标查询6.5 复合查询6.5.1 相关性算分6.5.2 布尔查询 7 搜索结果处理7.1 排序7.1.1 普通字段排序7.1.2 地理坐标排序 前言 Elast…