vue实现前端控制动态路由的示例代码

 更新时间:2025年04月01日 09:27:23   作者:聂聂脸  
本文主要介绍了vue实现前端控制动态路由的示例代码,通过这些步骤,可以有效地根据用户权限动态渲染前端路由,实现多用户权限系统,感兴趣的可以了解一下

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

动态路由的配置

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

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

// 创建路由实例
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实现前端控制动态路由的示例代码的文章就介绍到这了,更多相关vue 动态路由内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 说说Vue.js中的functional函数化组件的使用

    说说Vue.js中的functional函数化组件的使用

    这篇文章主要介绍了说说Vue.js中的functional函数化组件的使用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-02-02
  • Vue slot插槽的使用详情

    Vue slot插槽的使用详情

    这篇文章主要介绍了Vue slot插槽的使用,在生活中很多地方都有插槽,电脑usb的插槽,插板当中的电源插槽,插槽的目的是为了让我们原来的设备具备更多的扩展性比如电脑的USB我们可以插入U盘,手机,鼠标,键盘等等,下面文章就来介绍Vue slot插槽是如何使用的
    2021-10-10
  • Vue使用Echart图标插件之柱状图

    Vue使用Echart图标插件之柱状图

    这篇文章主要为大家详细介绍了Vue使用Echart图标插件之柱状图,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • vue+echarts实现可拖动节点的折线图(支持拖动方向和上下限的设置)

    vue+echarts实现可拖动节点的折线图(支持拖动方向和上下限的设置)

    制作一个折线图用于显示当前24小时的数据,并且可以通过拖动折现图设置数据,接下来通过本文给大家分享vue+echarts实现可拖动节点的折线图(支持拖动方向和上下限的设置),感兴趣的朋友跟随一起学习吧
    2019-04-04
  • Vue.js学习笔记之 helloworld

    Vue.js学习笔记之 helloworld

    vue是法语中视图的意思,Vue.js是一个轻巧、高性能、可组件化的MVVM库,同时拥有非常容易上手的API。有需要的小伙伴可以参考下
    2016-08-08
  • Vue联动Echarts实现数据大屏展示

    Vue联动Echarts实现数据大屏展示

    这篇文章主要为大家介绍了Vue联动Echarts实现数据大屏的展示示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-04-04
  • vue实现移动端图片裁剪上传功能

    vue实现移动端图片裁剪上传功能

    这篇文章主要为大家详细介绍了vue实现移动端图片裁剪上传功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-08-08
  • vue如何引用其他组件(css和js)

    vue如何引用其他组件(css和js)

    本篇文章主要介绍了vue如何引用其他组件(css和js) ,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-04-04
  • Vue3利用自定义ref实现防抖功能

    Vue3利用自定义ref实现防抖功能

    在Vue3中,ref提供了访问组件内DOM元素和子组件实例的方法,防抖是一种限制函数调用频率的方法,即在一定时间内多次触发同一个函数,只执行最后一次触发的函数,本文将给大家介绍了Vue3如何利用自定义ref实现防抖,需要的朋友可以参考下
    2024-05-05
  • 前端框架Vue父子组件数据双向绑定的实现

    前端框架Vue父子组件数据双向绑定的实现

    Vue项目中经常使用到组件之间的数值传递,实现的方法很多,但是原理上基本大同小异。这篇文章将给大家介绍Vue 父子组件数据单向绑定与Vue 父子组件数据双向绑定的对比从而认识双向绑定
    2021-09-09

最新评论