有关vue路由的学习

导言

由于很久没碰前端了,碰到路由都不太会了。趁着后端对接来记录一下,就当复习。不过由于个人能力有限,这篇会偏向整个过程的实现逻辑,其中有很多具体的方法不会给来,有兴趣的可以去看一下源码~

目的:

搞清楚若依路由侧边栏菜单生成及展示的逻辑

侧边栏菜单sidebar-item应用的数据格式,后端数据所必需的字段和格式

前端对后端传来数据的处理

逻辑:

1.整个菜单应用逻辑

       1.前端接受后端对应的格式数据。
       2.将其根据Element-ui的<el-menu>所需的格式及用户角色对应改造成适合的列表存vuex里。
       3.在相应的布局页面(...\src\layout\components\Sidebar\index.vue)从vuex取出数据应用。
       4.在侧边栏展示和vue路由管理的对应跳转可以实现点击菜单跳转到对应页面

整体过程

1.前端请求与接收

1.路由守卫调用GenerateRoutes

在...\src\permission.js,有token且不在登录页。

          store.dispatch('GenerateRoutes').then(accessRoutes => {// 根据roles权限生成可访问的路由表router.addRoutes(accessRoutes) // 动态添加可访问路由表next({ ...to, replace: true }) // hack方法 确保addRoutes已完成})

调的是...src\store\modules\permission.js的,名字一样。

这里调完之后会把处理好的路由塞进路由表里

2.GenerateRoutes:
// 生成路由GenerateRoutes({ commit }) {// 返回一个新的 Promisereturn new Promise(resolve => {// 向后端请求路由数据getRouters().then(res => {console.log("后端返回的数据:",res);...});});}

主要是承担请求后端,改造数据和存数据到vuex的功能,代码2.数据改造有

3.请求方法:
// 获取路由
export const getRouters = () => {return request({headers: {isToken: true},url: 'api/Menus/GetUserMenus',method: 'get'})
}

2.数据改造及存储

在...\src\store\modules\permission.js

    // 生成路由GenerateRoutes({ commit }) {// 返回一个新的 Promisereturn new Promise(resolve => {// 向后端请求路由数据getRouters().then(res => {console.log("后端返回的数据:",res);// 深拷贝后端返回的路由数据const sdata = JSON.parse(JSON.stringify(res.data));const rdata = JSON.parse(JSON.stringify(res.data));// 过滤出适合侧边栏的路由const sidebarRoutes = filterAsyncRouter(sdata);// 过滤出重写的路由const rewriteRoutes = filterAsyncRouter(rdata, false, true);// 过滤出动态路由const asyncRoutes = filterDynamicRoutes(dynamicRoutes);// 添加一个重定向路由,处理未匹配的路径rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true });// 将动态路由添加到 Vue Routerrouter.addRoutes(asyncRoutes);// 提交 mutations 更新路由状态commit('SET_ROUTES', rewriteRoutes);commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes));commit('SET_DEFAULT_ROUTES', sidebarRoutes);commit('SET_TOPBAR_ROUTES', sidebarRoutes);// 解析 Promise,返回重写的路由resolve(rewriteRoutes);});});}

其中的三类路由:

sidebarRoutes:这些路由用于生成侧边栏菜单。它们通常是与用户可视导航相关的路由,
因此侧边栏会根据用户的角色或权限显示不同的菜单结构。rewriteRoutes:这些路由包含重写逻辑,主要用于处理应用中的实际导航和访问控制。
可以理解为对原始路由的一个“过滤”或“优化”,确保在需要时能够准确地导航或限制用户的访问。asyncRoutes:这些路由仅在特定条件下加载。它们通常与权限控制相关,因此需要在运行时动态地添加到Vue Router。通过这种方式,可以在不重新加载页面的情况下,根据用户角色或权限控制对不同路由的访问。

3.侧边栏菜单数据应用:

在...\src\layout\components\Sidebar\index.vue侧边栏组件

数据来源sidebarRouters是拿GenerateRoutes存进vuex的侧边栏路由菜单

  //...\src\store\modules\permission.jsSET_DEFAULT_ROUTES: (state, routes) => {state.defaultRoutes = constantRoutes.concat(routes)},//...\src\layout\components\Sidebar\index.vue...mapGetters(["sidebarRouters", "sidebar"]),

这个组件定义了侧边栏的样式等,主要还是sidebar-item组件

<template><div :class="{'has-logo':showLogo}" :style="{ backgroundColor: settings.sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground }"><logo v-if="showLogo" :collapse="isCollapse" /><el-scrollbar :class="settings.sideTheme" wrap-class="scrollbar-wrapper"><el-menu:default-active="activeMenu"  :collapse="isCollapse"  :background-color="settings.sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground"  :text-color="settings.sideTheme === 'theme-dark' ? variables.menuColor : variables.menuLightColor" :unique-opened="true" :active-text-color="settings.theme"  :collapse-transition="false" mode="vertical" > <!-- 遍历 sidebarRouters 数组,生成菜单项 --> <!-- 使用路由路径和索引生成唯一的 key --><!-- 将当前路由项传递给 sidebar-item 组件 --> <!-- 将当前路由的路径传递给 sidebar-item 组件 --><sidebar-itemv-for="(route, index) in sidebarRouters" :key="route.path  + index" :item="route"  :base-path="route.path" /></el-menu>
</el-scrollbar></div>
</template>
菜单组件sidebar-item介绍及其所需要的东西
介绍:

sidebar-item是若依自定义的一个组件,在...\src\layout\components\Sidebar\SidebarItem.vue

用于展示单个菜单项(侧边栏)。

根据...\src\layout\components\Sidebar\index.vue传过来的item,isNest,basePath等来确定菜单的展示样式(是否展示,是否下拉...)

源码学习:

template,用hidden控制是否展示,之后分两部分

1.传来的菜单只有一个子菜单/没有子菜单:

    <!-- 判断是否只有一个显示的子项且满足其他条件 --><!-- && (!onlyOneChild.children || onlyOneChild.noShowingChildren) && 要么 onlyOneChild 没有子项,要么它的所有子项都不可见。 --><templatev-if="hasOneShowingChild(item.children, item) && (!onlyOneChild.children || onlyOneChild.noShowingChildren) && !item.alwaysShow"><!-- 如果存在子项的 meta,使用 app-link 组件进行导航 --><app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path, onlyOneChild.query)"><!-- 渲染一个菜单项,index 为子项的路径 --><el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{ 'submenu-title-noDropdown': !isNest }"><!-- 显示子项的图标和标题,如果没有图标,则使用父项的图标 --><item :icon="onlyOneChild.meta.icon || (item.meta && item.meta.icon)" :title="onlyOneChild.meta.title" /></el-menu-item></app-link></template>

这段的处理就相当于把没有子菜单的直接展示,把只有一个子菜单的直接显示子菜单

如下图,系统管理只有菜单管理一个子菜单,所以直接展示了菜单管理:

hasOneShowingChild方法分三种情况:

// 当存在且仅有一个可见的子项时:
// 如果 showingChildren.length === 1,则返回 true,表示有一个可显示的子项。// 当没有可见子项时:
// 如果 showingChildren.length === 0,则会设置 this.onlyOneChild 为一个新的对象,且返回 true。这表示在没有显示的子项的情况下,父项仍然需要被显示。// 如果有多个可见子项时:
// 如果有两个或更多可见子项,则返回 false,表示没有唯一的可显示子项。hasOneShowingChild(children = [], parent) {if (!children) {children = [];}const showingChildren = children.filter(item => {if (item.hidden) {return false} else {// Temp set(will be used if only has one showing child)this.onlyOneChild = itemreturn true}})// When there is only one child router, the child router is displayed by defaultif (showingChildren.length === 1) {return true}// Show parent if there are no child router to displayif (showingChildren.length === 0) {this.onlyOneChild = { ...parent, path: '', noShowingChildren: true }return true}return false},

2.第二部分:

绑定完当前菜单后嵌套调sidebar-item,循环绑该菜单项的子菜单

    <!-- 如果不满足上述条件,则渲染一个子菜单 --><!-- :index 用于设置 <el-submenu> 组件的唯一标识符。这是一个字符串或路径,表示菜单项的唯一键,通常用于导航或路由。 --><el-submenu v-else ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body><template slot="title"><!-- 渲染子菜单的标题,如果存在 meta,则显示图标和标题 --><item v-if="item.meta" :icon="item.meta && item.meta.icon" :title="item.meta.title" /></template><!-- :basepath 是一个自定义的 prop,用于传递子菜单项的基础路径。<sidebar-item> 组件中的 basepath 主要用于生成子项的相对路径,或者作为子项路径的起点。 --><!-- 循环调用绑子菜单 --><sidebar-item v-for="child in item.children" :key="child.path" :is-nest="true" :item="child":basepath="resolvePath(child.path)" class="nest-menu" />-</el-submenu>

3.resolvePath方法

//用于解析并生成完整的导航路径resolvePath(routePath, routeQuery) {console.log("routePath",routePath);console.log("分割符");if (isExternal(routePath)) {//是外链return routePath}//如果 basePath 是外部链接,则返回 basePath。在这种情况下,//routePath 被忽略,最终导航会指向 basePath,这是因为 basePath 已经是一个完整的外部链接。if (isExternal(this.basePath)) {return this.basePath}// 如果提供了 routeQuery,则解析查询字符串,并生成包含 path 和 query 的对象:if (routeQuery) {let query = JSON.parse(routeQuery);//返回的对象包含 path 和 query 字段,以便在导航时附加查询参数,如字典数据return { path: path.resolve(this.basePath, routePath), query: query }}//如果 routeQuery 为空,且路径都为内部链接,则使用 path.resolve(this.basePath, routePath) 将 routePath 解析为基于 basePath 的完整路径。return path.resolve(this.basePath, routePath)}

4.有关alwaysShow

在路由表有相关介绍,我这没用这个

/*** Note: 路由配置项** hidden: true                     // 当设置 true 的时候该路由不会再侧边栏出现 如401,login等页面,或者如一些编辑页面/edit/1* alwaysShow: true                 // 当你一个路由下面的 children 声明的路由大于1个时,自动会变成嵌套的模式--如组件页面*                                  // 只有一个时,会将那个子路由当做根路由显示在侧边栏--如引导页面*                                  // 若你想不管路由下面的 children 声明的个数都显示你的根路由*                                  // 你可以设置 alwaysShow: true,这样它就会忽略之前定义的规则,一直显示根路由
...*/
所需要的东西:

大概长这样:

侧边栏菜单和路由表的关系

  1. 数据来源:

    • 侧边栏菜单的构建通常基于路由表。路由表定义了所有可用的路由及其对应的组件、权限等信息。
    • 当从后端获取路由数据时,侧边栏菜单会根据这些数据生成相应的菜单项。
  2. 动态生成:

    • 当用户的权限发生变化(如角色变更)时,可能需要重新生成可访问的路由和侧边栏菜单。
    • 例如,GenerateRoutes 方法从后端获取路由数据后,通过权限过滤生成 accessRoutes,同时生成相应的侧边栏菜单。
  3. 结构一致性:

    • 侧边栏菜单和路由表通常遵循相同的数据结构。侧边栏菜单的每个菜单项通常会对应路由表中的一条路由,这样在导航时可以确保用户点击菜单后,能够正确匹配到相应的组件。
  4. 管理与更新:

    • router.addRoutes(accessRoutes) 中,动态添加可访问的路由表。这意味着应用程序的路由结构是可变的,可以根据用户的角色和权限动态更新。
    • 同时,更新路由表后,侧边栏菜单也会根据新的路由数据进行重新渲染,以反映最新的导航结构。
  5. 导航功能:

    • 用户通过侧边栏菜单进行导航,实际背后的路由表则决定了哪些组件被加载和渲染。因此,侧边栏菜单的可用性和功能直接依赖于路由表的配置。

      侧边栏菜单是用户与应用程序交互的界面,而路由表则是管理应用程序导航和组件渲染的核心结构。两者通过相同的数据模型和动态更新机制,保持一致性和功能性。

总结:

搞了很多天,主要还是基础和思路,很多时间都不知道自己在干嘛,其中的很多细节都还没搞懂,不过写了这篇,也大概能捋一下思路。

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

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

相关文章

基于springboot vue 校园失物招领平台的设计与实现

博主介绍&#xff1a;专注于Java&#xff08;springboot ssm springcloud等开发框架&#xff09; vue .net php phython node.js uniapp小程序 等诸多技术领域和毕业项目实战、企业信息化系统建设&#xff0c;从业十五余年开发设计教学工作☆☆☆ 精彩专栏推荐订阅☆☆☆☆…

SAP_SD模块-销售订单抬头折扣金额分摊到行项目的业务记录

前言&#xff1a; 本文主要是记录24年9月份支持财务月结过程中&#xff0c;用户提出的一个问题&#xff1a;“为什么KE30有部分物料9月份的销售数量少于FAGLL03H的销售数量&#xff1f;&#xff1f;”&#xff0c;主要包括以下两个内容&#xff1b; 1、问题发生的场景复现&am…

毕设分享 基于协同过滤的电影推荐系统

文章目录 0 简介1 设计概要2 课题背景和目的3 协同过滤算法原理3.1 基于用户的协同过滤推荐算法实现原理3.1.1 步骤13.1.2 步骤23.1.3 步骤33.1.4 步骤4 4 系统实现4.1 开发环境4.2 系统功能描述4.3 系统数据流程4.3.1 用户端数据流程4.3.2 管理员端数据流程 4.4 系统功能设计 …

【hot100-java】二叉树的最近公共祖先

二叉树篇 我觉得是比两个节点的深度&#xff0c;取min&#xff08;一种情况&#xff09; DFS解题。 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode(int x) { val x; }* }*/ clas…

Apache Flink Dashboard

1、Overview Apache Flink Web Dashboardhttp://110.40.130.231:8081/#/overview 这张图片显示的是Apache Flink的Web UI界面&#xff0c;其中包含了以下几个部分&#xff1a; Available Task Slots: 显示当前可用的任务槽位数量。任务槽位是指Flink集群中可用于运行任务的资…

Django makemigrations时出现ModuleNotFoundError: No module named ‘MySQLdb‘

使用Python 3.11、Django 5.1.2 写完model进行makemigrations时出现报错 查找资料发现说是mysqldb适用于Python2&#xff0c;不支持Python3&#xff1b;python3可以使用pymysql 安装pymsql pip install pymysql 然后要在项目的__init__.py中加如下代码&#xff1a; import …

K8s(学习笔记)

swap分区是什么呀&#xff1f; 什么是ipvs呀&#xff1f; yaml是什么呀&#xff1f;&#xff1f;&#xff1f; p20看不下去了&#xff01;&#xff01;&#xff01;

【LeetCode】修炼之路-0004-Median of Two Sorted Arrays【python】

题目 Given two sorted arrays nums1 and nums2 of size m and n respectively, return the median of the two sorted arrays. The overall run time complexity should be O(log (mn)). Example 1: Input: nums1 [1,3], nums2 [2] Output: 2.00000 Explanation: merged…

SPIE出版-EI会议-人机交互 虚拟现实 <<< 11月杭州

EI、Scopus检索|人机交互与虚拟现实国际会议征稿进行中❗会议已通过SPIE出版❗ 2024人机交互与虚拟现实国际会议 ✅大会时间&#xff1a;2024年11月15-17日 ✅大会地点&#xff1a;中国-杭州 ✅报名/截稿&#xff1a;2024年10月15日&#xff08;团队投稿可享优惠&#xff…

实现std::sort,replace,fill,accumulate,equal等函数

std::sort /// <summary>/// std::sort 是从小到大排列的/// </summary>/// <typeparam name"IteratorClass"></typeparam>/// <typeparam name"ComparingFunctions"></typeparam>/// <param name"itBegin&qu…

基于IDEA+SpringBoot+Vue+Uniapp的投票评选小程序系统的详细设计和实现

2. 详细视频演示 文章底部名片&#xff0c;联系我获取更详细的演示视频 3. 论文参考 4. 项目运行截图 代码运行效果图 代码运行效果图 代码运行效果图 代码运行效果图 代码运行效果图 5. 技术框架 5.1 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框…

大数据毕业设计选题推荐-B站热门视频数据分析-Python数据可视化-Hive-Hadoop-Spark

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

AI助力农作物自动采摘,基于嵌入式端超轻量级模型LeYOLO全系列【n/s/m/l】参数模型开发构建作物生产场景下番茄采摘检测计数分析系统

去年十一那会无意间刷到一个视频展示的就是德国机械收割机非常高效自动化地24小时不间断地在超广阔的土地上采摘各种作物&#xff0c;专家设计出来了很多用于采摘不同农作物的大型机械&#xff0c;看着非常震撼&#xff0c;但是我们国内农业的发展还是相对比较滞后的&#xff0…

计算机的错误计算(一百一十八)

摘要 探讨一个不动点的计算精度问题。 不动点是一类特殊的循环迭代。它有形式 例1. 已知迭代[1] 计算 显然&#xff0c;每个 均为 0.5 . 不妨在Visual Studio 2010 下用下列C语言代码计算&#xff1a; #include <stdio.h> #include <math.h>int main() {do…

【大语言模型-论文速读】GPT的不确定性判断

【大语言模型-论文精读】GPT’s Judgements Under Uncertainty Authors: Payam Saeedi and Mahsa Goodarzi 论文&#xff1a;https://arxiv.org/pdf/2410.02820 文章标题翻译 GPT的不确定性判断 Payam Saeedi Rochester Institute of Technology Mahsa Goodarzi The State …

【exp报错注入】

整数范围 最大整数 exp 函数介绍 报错盲注注入 payload分析 709C-ASCII 值就等于我们下面的 7091-1 &#xff0c;C就是我们要猜的值&#xff0c;当我们猜测的值和ASCII码相等时&#xff0c;那么exp就不会出现报错&#xff0c;因为1-1还是等于709&#xff1a; 练习 id1 an…

【AIGC】OpenAI API在快速开发中的实践与应用:优化ChatGPT提示词Prompt加速工程

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AIGC | ChatGPT 文章目录 &#x1f4af;前言&#x1f4af;使用最新型号确保最佳实践利用最新模型进行高效任务处理为什么要选择最新模型&#xff1f;结论 &#x1f4af;指令与上下文的分隔最佳实践分隔指令和上下文的重要性使用符…

Win32 API 控制台鼠标操作、坐标获取与相关函数介绍

Win32 API 控制台鼠标操作、坐标获取与相关函数介绍 一、前置介绍读取控制台输入缓冲区数据 ReadConsoleInput 函数控制台输入缓冲区中的输入事件 INPUT_RECORD 结构鼠标输入事件 MOUSE_EVENT_RECORD 结构更改输入模式 SetConsoleMode 函数 二、鼠标坐标获取(以下代码环境为 VS…

PCL 3D-SIFT关键点检测(Z方向梯度约束

目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.1.1 SIFT关键点检测 2.1.2 可视化函数 2.2完整代码 三、实现效果 PCL点云算法汇总及实战案例汇总的目录地址链接&#xff1a; PCL点云算法与项目实战案例汇总&#xff08;长期更新&#…

SQL优化 where谓词条件OR优化

1.测试表&#xff0c;及测试语句where条件中OR对应两个字段选择度很高 create table t618 as select * from dba_objects; select object_name from t618 where (object_id12043 or DATA_OBJECT_ID12043) and STATUSVALID; 2.没有索引情况下&#xff0c;全表扫描逻辑读…