vue如何实现前端控制动态路由

news2025/4/13 6:58:59

在 Vue.js 中,动态路由是一种根据不同用户权限或其他因素动态改变路由列表的功能。这种机制允许开发者根据后端提供的权限数据动态渲染前端路由,实现多用户权限系统,不同用户展示不同的导航菜单。

动态路由的配置

动态路由的配置涉及到前端路由的动态加载和解析。通常,动态路由的数据存储在数据库中,前端通过接口获取当前用户对应的路由列表并进行渲染。以下是实现动态路由的基本步骤:

  1. 静态路由配置:首先,需要配置静态路由,如登录页、首页等。这些路由通常不会改变,可以直接写在路由配置文件中。

// 创建路由实例
const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: allRoutes
})
// 所有路由定义(静态+动态)
const allRoutes = [
  // 基础路由
  {
    path: '/',
    name: 'login',
    component: () => import("@/views/LoginView.vue")
  },
  {
    path: '/404',
    name: '404',
    component: () => import('@/views/Error/404View.vue')
  },
  // 动态路由容器(登录后内容)
  {
    path: '/layout',
    name: 'layout',
    component: () => import('@/Layout/MainLayout.vue'),
    children: [] // 初始为空,动态注入路由
  },
]

动态路由获取:在用户登录后,前端调用后端接口获取用户对应的权限类型role。

// 需要权限控制的路由配置(扁平化结构更易管理)
const dynamicRouteConfigs = [
  {
    path: '/home', // 注意使用相对路径
    name: 'home',
    component: () => import('@/views/HomeView.vue'),
    meta: { 
      title: '首页', 
      icon: 'House',
      roles: ['*'] // *表示所有登录用户
    }
  },
  {
    path: 'user/list',
    name: 'UserList',
    component: () => import('@/views/user/ListView.vue'),
    meta: { 
      title: '用户列表',
      roles: ['1','2']
    }
  },
  {
    path: 'user/role',
    name: 'UserRole',
    component: () => import('@/views/user/RoleView.vue'),
    meta: { 
      title: '角色管理',
      roles: ['1']
    }
  }
]

路由过滤的函数

// 权限过滤方法修正
const filterRoutes = (routes, roles) => {
  // 递归处理每个路由节点
  return routes.filter(route => {
    // 获取当前路由需要的权限角色
    const requiredRoles = route.meta?.roles || []
    // 检查当前路由是否满足权限要求
    const hasPermission = requiredRoles.includes('*') || requiredRoles.includes(roles + '')
    // 递归处理子路由(关键修改点)
    if (route.children) {
      const filteredChildren = filterRoutes(route.children, roles)
      // 保留有效子路由:只有当子路由存在时才保留children
      route.children = filteredChildren.length ? filteredChildren : undefined
    }
    /* 
      路由保留条件(核心逻辑):
      1. 当前路由自身有权限 或 
      2. 存在有效的子路由(即使当前路由没有权限,但子路由有权限时保留父级容器)
    */
    return hasPermission || (route.children && route.children.length > 0)
  })
}

动态添加路由,先清空已有的动态路由,然后再调用添加路由的函数进行添加,

// 动态添加路由到layout
const addDynamicRoutes = (roles) => {
  // 清空已有动态路由
  const layout = router.getRoutes().find(r => r.name === 'layout')
  layout.children.forEach(child => {
    router.removeRoute(child.name)
  })
  // 过滤并添加新路由
  const allowedRoutes = filterRoutes(dynamicRouteConfigs, loginStore().roles); 
  allowedRoutes.forEach(route => { router.addRoute('layout', route); });
  console.log(allowedRoutes);
  sessionStorage.setItem('menuPath',JSON.stringify(allowedRoutes));//存储的筛选过的动态路由
  sessionStorage.setItem('menuName',JSON.stringify(router.getRoutes()));//存储的所有动态路由
  console.log(router.getRoutes());
  // 确保404最后处理
  router.addRoute({ 
    path: '/:pathMatch(.*)*',
    redirect: '/404'
  })
}

 导航守卫部分,路由跳转前的操作。

获取用户状态存储实例,检测登录状态;判断用户未登录时直接跳转到登录页进行登录;已登录访问登录页处理,防止已登录用户重复访问登录页;动态路由注入。

使用router.addRoute()注入路由;路由跳转处理,清除旧路由(避免重复);

// 路由守卫修改部分(router/index.ts)
router.beforeEach(async (to, from, next) => {
  const store = loginStore()
  const isLogin = !!store.id
  // 未登录状态处理
  if (!isLogin) {
    return to.path === '/' ? next() : next('/')
  }
  // 已登录但访问登录页时重定向
  if (to.path === '/') {
    return next('/home')
  }
  // 动态路由加载逻辑
  if (!store.routesLoaded) {
    try {
      // 直接从store获取已保存的角色信息
      const userRoles = store.roles
      console.log(userRoles);
      // 如果角色信息不存在则抛出错误
      if (!userRoles || userRoles.length === 0) {
        throw new Error('用户角色信息未获取')
      }
      // 添加动态路由
      addDynamicRoutes(userRoles)
      // 在添加路由后打印
      console.log('当前所有路由:', router.getRoutes().map(r => r.path))
      // 更新加载状态
      store.setRoutesLoaded(true)
      // 使用replace方式跳转避免重复记录历史
      return next({ ...to, replace: true })
    } catch (error) {
      console.error('路由加载失败:', error)
      // 清除用户状态并跳转登录页
      store.$reset()
      return next('/')
    }
  }
  next()
})

最后,总结整个流程,强调关键点,帮助用户全面理解路由守卫的工作机制和实现动态路由加载的正确方法。

本文详细介绍了在Vue.js中实现动态路由和权限控制的步骤,包括路由配置、动态路由获取、路由过滤、动态添加路由以及导航守卫的使用。通过这些步骤,可以有效地根据用户权限动态渲染前端路由,实现多用户权限系统。

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

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

相关文章

《构建有效的AI代理》学习笔记

原文链接:https://www.anthropic.com/engineering/building-effective-agents 《构建有效的AI代理》学习笔记 一、概述 核心结论 • 成功的AI代理系统往往基于简单、可组合的模式,而非复杂框架。 • 需在性能、成本与延迟之间权衡,仅在必要时增加复杂度…

数据处理专题(四)

目标 使用 Matplotlib 进行基本的数据可视化。‍ 学习内容 绘制折线图 绘制散点图 绘制柱状图‍ 代码示例 1. 导入必要的库 import matplotlib.pyplot as pltimport numpy as npimport pandas as pd 2. 创建示例数据集 # 创建示例数据集data { 月份: [1月, 2月, 3…

【目标检测】【深度学习】【Pytorch版本】YOLOV1模型算法详解

【目标检测】【深度学习】【Pytorch版本】YOLOV1模型算法详解 文章目录 【目标检测】【深度学习】【Pytorch版本】YOLOV1模型算法详解前言YOLOV1的模型结构YOLOV1模型的基本执行流程YOLOV1模型的网络参数YOLOV1模型的训练方式 YOLOV1的核心思想前向传播阶段网格单元(grid cell)…

云钥科技多通道工业相机解决方案设计

项目应用场景分析与需求挑战 1. 应用场景 ‌目标领域‌:工业自动化检测(如精密零件尺寸测量、表面缺陷检测)、3D立体视觉(如物体建模、位姿识别)、动态运动追踪(如高速生产线监控)等。 ‌核心…

从零到一:ESP32与豆包大模型的RTC连续对话实现指南

一、对话效果演示 ESP32与豆包大模型的RTC连续对话 二、ESP-ADF 介绍 乐鑫 ESP-ADF(Espressif Audio Development Framework)是乐鑫科技(Espressif Systems)专为 ESP32 系列芯片开发的一款音频开发框架。它旨在简化基于 ESP32 芯…

【深度学习与实战】2.3、线性回归模型与梯度下降法先导案例--最小二乘法(向量形式求解)

为了求解损失函数 对 的导数,并利用最小二乘法向量形式求解 的值‌ 这是‌线性回归‌的平方误差损失函数,目标是最小化预测值 与真实值 之间的差距。 ‌损失函数‌: 考虑多个样本的情况,损失函数为所有样本的平方误差之和&a…

【Django】教程-2-前端-目录结构介绍

【Django】教程-1-安装创建项目目录结构介绍 3. 前端文件配置 3.1 目录介绍 在app下创建static文件夹, 是根据setting中的配置来的 STATIC_URL ‘static/’ templates目录,编写HTML模板(含有模板语法,继承,{% static ‘xx’ …

详解list容器

1.list的介绍 list的底层结构是双向带头循环链表,允许随机的插入和删除,但其内存空间不是连续的。随机访问空间能力差,需要从头到尾遍历节点,不像vector一样高效支持 2.list的使用 构造函数 1.默认构造函数:创建一个…

leetcode_977. 有序数组的平方_java

977. 有序数组的平方https://leetcode.cn/problems/squares-of-a-sorted-array/ 1.题目 给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。 示例 1: 输入:nums [-4,-1…

网络探索之旅:网络原理(第二弹)

上篇文章,小编分享了应用层和传输层深入的一点的知识,那么接下来,这篇文章,继续分享网络层和数据链路层。 网络层 了解这个网络层,那么其实就是重点来了解下IP这个协议 对于这个协议呢,其实也是和前面的…

深入剖析 JVM:从组成原理到调优实践

深入剖析 JVM:从组成原理到调优实践 深入剖析 JVM:从组成原理到调优实践一、JVM 组成架构:运行 Java 程序的 “幕后引擎”1.1 内存结构:数据存储的 “分区管理”1.2 执行引擎:字节码的 “翻译官”1.3 本地方法接口&…

阿里云下一代可观测时序引擎-MetricStore 2.0

作者:徐昊(博澍) 背景 作为可观测场景使用频度最高的数据类型,Metrics 时序数据在可观测领域一直占有着重要地位,无论是从全局视角来观测系统整体状态,还是从大范围数据中定位某一个异常的位置&#xff0…

从入门到精通【 MySQL】 数据库约束与设计

文章目录 📕1. 数据库约束✏️1.1 NOT NULL 非空约束✏️1.2 DEFAULT 默认值约束✏️1.3 UNIQUE 唯一约束✏️1.4 PRIMARY KEY 主键约束✏️1.5 FOREIGN KEY 外键约束✏️1.6 CHECK 约束 📕2. 数据库设计✏️2.1 第一范式✏️2.2 第二范式✏️2.3 第三范…

Dubbo 通信流程 - 服务的调用

Dubbo 客户端的使用 在 Dubbo 应用中,往类成员注解 DubboReference,服务启动后便可以调用到远端: Component public class InvokeDemoFacade {AutowiredDubboReferenceprivate DemoFacade demoFacade;public String hello(String name){// …

【数据结构】哈夫曼树

哈夫曼树 在学习哈夫曼树之前,先了解以下几个概念: 一:**路径长度:**在一棵树中,从一个节点到另一个节点所经过的“边”的数量,被我们称为两个节点之间的路径长度。 二:**树的路径长度&#xf…

HCIP(TCP)(2)

1. TCP三次握手 SYN (同步序列编号) 报文: 客户端发送 SYN 报文,开始建立连接,并初始化序列号。 SYN-ACK (同步序列编号-确认) 报文: 服务器收到 SYN 报文后,回复 SYN-ACK 报文,确认连接请求,并初始化自己的序列号和确…

基于Web的交互式智能成绩管理系统设计

目录 摘要 绪论 一、应用背景 二、行业发展现状 三、程序开发的重要意义 四、结语 1 代码 2 数据初始化模块 3 界面布局模块 4 核心功能模块 5 可视化子系统 6 扩展功能模块 7 架构设计亮点 功能总结 一、核心数据管理 二、智能分析体系 三、可视化系统 四、扩…

k8s日志管理

k8s日志管理 k8s查看日志查看集群中不是完全运行状态的pod查看deployment日志查看service日志进入pod的容器内查看日志 管理k8s组件日志kubectl logs查看日志原理 管理k8s应用日志收集k8s日志思路收集标准输出收集容器中日志文件 k8s查看节点状态失败k8s部署prometheus监控 k8s…

element-plus中,Loading 加载组件的使用

一.基本使用 给一个组件&#xff0c;如&#xff1a;table表格&#xff0c;加上v-loading"true"即可。 举例&#xff1a;复制如下代码。 <template><el-table v-loading"loading" :data"tableData" style"width: 100%"><…

Mybatis_Plus中的常用注解

目录 1、TableName TableId TableId的type属性 TableField 1、TableName 经过以上的测试&#xff0c;在使用MyBatis-Plus实现基本的CRUD时&#xff0c;我们并没有指定要操作的表&#xff0c;只是在 Mapper接口继承BaseMapper时&#xff0c;设置了泛型User&#xff0c;而操…