vue 实现动态路由

news2024/12/23 12:28:00

vue-router对象中的addRoutes,用它来动态添加路由配置

格式:

router.addRoutes([路由配置对象])
this.$router.addRoutes([路由配置对象])

举个例子:

// 按钮
<button @click="hAddRoute">addRoute</button>

// 回调
hAddRoute() {
    this.$router.addRoutes([{
        path: '/abc',
        component: () => import('@/views/abc'),
        }])
},

我是以 vue-admin-template 为例,做如下演示:

在router/index.js中的路由配置中 只保留静态路由(因为我们要动态的添加))

const createRouter = () => new Router({
  // mode: 'history', // require service support
  scrollBehavior: () => ({ y: 0 }),
  routes: [...constantRoutes]   //因为要动态添加动态路由,所以这里只写静态路由
})

在permission.js中引入,并使用addRoutes动态添加

这个是 router 下的 index.js中定义的 静态路由、动态路由

接下来来看 在permission.js中引入的内容,

// 引入所有的动态路由表(未经过筛选)
+ import router, { asyncRoutes } from '@/router'

const whiteList = ['/login', '/404']
router.beforeEach(async(to, from, next) => {
  // 开启进度条
  NProgress.start()
  // 获取本地token 全局getter
  const token = store.getters.token
  if (token) {
    // 有token
    if (to.path === '/login') {
      next('/')
    } else {
      if (!store.getters.userId) {
        await store.dispatch('user/getUserInfo')
        // 改写成动态添加的方式
+       router.addRoutes(asyncRoutes)
      }
      next()
    }
  } else {
    // 没有token
    if (whiteList.includes(to.path)) {
      next()
    } else {
      next('/login')
    }
  }
  // 结束进度条
  NProgress.done()
})

如果我们希望在调用addRoutes方法之后,要路由数据立刻反映到菜单中,我们需要想一个额外的方法,思考一下,vue开发中,哪个技术可以保证响应式特性还可以动态修改? vuex!

补充模块,在src/store/modules下补充menu.js模块 (定义vuex管理菜单数据

import { constantRoutes } from '@/router' 
export default {
  namespaced: true,
  // 公共数据
  state: {
    // 本地取一下token
    menuList: [] // 所有可以访问的路由配置
  },
  mutations: {
    setMenuList(state, asyncRoutes) { 
      console.log('asyncRoutes', asyncRoutes) //第二个参数是调用mutatains时传过来的动态路由参数
      state.menuList = [...constantRoutes, ...asyncRoutes]
    }
  }
}

当然,要在 src/store/index.js 中注册这个模块

修改src/permission.js中的代码

if (!store.getters.userId) {
        await store.dispatch('user/getUserInfo')

        // 动态添加可以访问的路由设置
        router.addRoutes(asyncRoutes)

        // 根据用户实际能访问几个页面来决定从整体8个路由设置
        // 中,过滤中出来几个,然后保存到vuex中
    ++   store.commit('menu/setMenuList', asyncRoutes)  //把动态路由存入vuex中
      }

在src\layout\components\Sidebar\index.vue文件中,修改

routes() {
  // 拿到的是一个完整的包含了静态路由和动态路由的数据结构
  return this.$store.state.menu.menuList
}

上一步我们实现了: 1.把动态路由通过addRoutes动态添加到了路由系统里, 2. 把动态路由保存到vuex的menu中,

但是我们没有和权限数据做搭配,接下来我们通过接口返回的权限数据对动态菜单做过滤处理,以确定完成菜单与用户权限相关。

接下来就是 调接口,后端返给你菜单数据:

用户能访问哪些页面是通过actions获取到的,只需要从action中返回即可

在permission.js中获取action的返回值并过滤

if (!store.getters.userId) {
        // 有token,要去的不是login,就直接放行
        // 进一步获取用户信息
        // 发ajax---派发action来做
        const menus = await store.dispatch('user/getUserInfo')
        console.log('当前用户能访问的页面', menus)
        console.log('当前系统功能中提供的所有的动态路由页面是', asyncRoutes)
        // 根据本用户实际的权限menus去 asyncRoutes 中做过滤,选出本用户能访问的页面

        const filterRoutes = asyncRoutes.filter(route => {
          const routeName = route.children[0].name
          return menus.includes(routeName)
        })

        // 一定要在进入主页之前去获取用户信息

        // addRoutes用来动态添加路由配置
        // 只有在这里设置了补充了路由配置,才可能去访问页面
        // 它们不会出现左侧
        router.addRoutes(filterRoutes)

        // 把它们保存在vuex中,在src\layout\components\Sidebar\index.vue
        // 生成左侧菜单时,也应该去vuex中拿
        store.commit('menu/setMenuList', filterRoutes)
      }

问题

如果我们刷新浏览器,会发现跳到了404页面

对于addRoute添加的路由,在刷新时会白屏

原因

现在我们的路由设置中的404页处在中间位置而不是所有路由的末尾了。

解决

把404页改到路由配置的最末尾就可以了

 filterRoutes.push({ path: '*', redirect: '/404', hidden: true }) 
//解决刷新去404页面
 // 解决刷新出现的白屏bug
  next({
    ...to, // next({ ...to })的目的,是保证路由添加完了再进入页面 (可以理解为重进一次)
    replace: true // 重进一次, 不保留重复历史
  })

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

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

相关文章

感染了恶意软件怎么办?

近日&#xff0c;研究人员披露了一种恶意软件&#xff0c;这种恶意软件已经感染了一系列广泛的 Linux 和 Windows 设备。恶意软件攻击事件的频繁发生&#xff0c;除了黑客的恶意攻击外&#xff0c;还有企业内部自身的问题&#xff0c;下面列举了7种容易感染恶意软件的途径和解决…

2023年2月软考高级-信息系统项目管理师【报名入口】

信息系统项目管理师是全国计算机技术与软件专业技术资格&#xff08;水平&#xff09;考试&#xff08;简称软考&#xff09;项目之一&#xff0c;是由国家人力资源和社会保障部、工业和信息化部共同组织的国家级考试&#xff0c;既属于国家职业资格考试&#xff0c;又是职称资…

coresight(六) power requestor

power requestor power requestor属于coresight组件。这个组件用来控制系统的power domain&#xff0c;最多可以控制32个。 如果没有power requestor&#xff0c;通过DAP&#xff0c;只能对整个coresight系统进行上下电操作&#xff0c;但是有了power requestor&#xff0c;可…

2Pai半导体-推出π122E61双通道数字隔离器 智能分压技术 兼容代替Si8622ET-IS

2Pai半导体-推出π122E61双通道数字隔离器 智能分压技术 兼容代替Si8622ET-IS 电路简单、稳定性更高 &#xff0c;具有出色的性能特征和可靠性&#xff0c;整体性能优于光耦和基于其他原理的数字隔离器产品。 产品传输通道间彼此独立&#xff0c;可实现多种传输方向的配置&…

开源工作流可以解决什么问题?

要了解这个问题&#xff0c;就需要先弄清楚相关概念。为什么要使用开源工作流&#xff0c;可以解决什么问题&#xff1f;如果要实现某个业务目标&#xff0c;提高办公协作效率&#xff0c;就可以用开源工作流在多个参与者之间&#xff0c;借助计算机&#xff0c;按照某种预定规…

Oracle重写sql经典50题

Oracle重写sql经典50题oracle与mysql还是有区别的表的数据只能一条一条的插日期的插入不能想mysql一样直接插&#xff0c;得转换格式mysql里的ifnull&#xff0c;oracle里没有这个函数&#xff0c;用nvl代替mysql里的limit在oracle里也没有&#xff0c;要用rownum查询&#xff…

力扣 76. 最小覆盖子串

一、题目 二、 示例 三、提示 四、 思路与代码实现 1. 思路 本题&#xff0c; 套用的是滑动窗口算法模板;初始化左右窗口边界指针&#xff08;要方便源串取值&#xff09; left 0, right 0&#xff0c; 为什么这样初始化&#xff1f; 若设置窗口索引为左闭右闭区间&#xf…

英语学习打卡day8

2023.1.29 1. affluent adj.富裕的&#xff0c;富足的&#xff0c;流畅的n.支流&#xff0c;富人 flu交通流动、发达-流畅的 affluent society affluent neighborhood 2.conception 概念&#xff0c;观念;受孕&#xff0c;怀孕 conceive v.构思&#xff0c;设想;使受孕&…

【Redis | 黑马点评】短信登陆

文章目录项目概述项目前置准备短信登陆基于Session实现登录流程实现发送短信验证码功能实现短信验证码登录和注册功能实现登录校验拦截器隐藏用户敏感信息集群的Session共享问题基于Redis实现共享Session登录登录拦截器的优化项目概述 短信登录 这一块我们会使用redis共享sess…

ExecutorService线程池

文章目录ExecutorService线程池1 ExecutorService API 介绍1.1 api1.1.1 awaitTermination 方法1.1.2 invokeAll 方法1.1.3 invokeAny方法1.1.4 shutdown 方法1.1.5 shutdownNow方法1.1.6 isShutdown方法1.1.7 submit方法1.1.8 isTerminated方法ExecutorService线程池 1 Execu…

Makefile学习笔记(一)

背景 最近在看ATF代码的时候&#xff0c;想要编译下&#xff0c;实施起来遇到一些问题&#xff0c;其中makefile有些命令&#xff0c;语法不是很清晰&#xff0c;故希望重新系统学习下。学习主要参考跟我一起写Makefile-陈皓.pdf。 第一部分、概述 makefile解决的问题&#…

周期矩形波的傅里叶级数展开(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 当脉冲信号周期不变&#xff0c;脉冲宽度变大时&#xff0c;相邻谱线间隔不变&#xff0c;频谱包络线的零点频率逐渐变小&…

git查看分支、创建分支、合并分支

一、查看的git命令如下&#xff1a; git branch 列出本地已经存在的分支&#xff0c;并且当前分支会用*标记 git branch -r 查看远程版本库的分支列表 git branch -a 查看所有分支列表&#xff08;包括本地和远程&#xff0c;remotes/开头的表示远程分支&#xff09; git bran…

9、位和逗号的运算符与表达式

目录 一、位逻辑运算符与位逻辑表达式 1. 位逻辑运算符 2. 位逻辑表达式 二、逗号运算符与逗号表达式 一、位逻辑运算符与位逻辑表达式 1. 位逻辑运算符 位逻辑运算符包括位逻辑与、位逻辑或、位逻辑非和取补 注意&#xff1a;表中除了最后一个运算符是单目运算符外&…

PC 性能自动化工具技术方案及说明

● 需求背景 Kim PC端在每一个版本的迭代过程中&#xff0c;由于各版本的功能改动较多&#xff0c;为了避免在发布新版本时性能不会出现“大跳水”的情况&#xff0c;需要针对每一个版本进行性能测试。由于人工手动测试所需时间较长&#xff0c;且存在参数不准确、时间不可控等…

基于Java+SpringBoot+vue+element驾校管理系统设计和实现

博主介绍&#xff1a;✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

详解vue组件(属性、事件和插槽)

一、属性 1.自定义属性props 可以得出props 可以显示定义一个或一个以上的数据&#xff0c;对于接收的数据&#xff0c;可以是各种数据类型&#xff0c;同样也可以传递一个函数。通过一般属性实现父向子通信&#xff1b;通过函数属性实现子向父通信 2.inheritAttrs 3. data与…

十、顺序存储二叉树、线索化二叉树

1、二叉树顺序存储 1.1 特点 顺序二叉树通常只考虑完全二叉树第n个元素的左子节点为2*n1第n个元素的右子节点为2*n2第n个元素的父节点为(n-1)/2 n&#xff1a;表示二叉树中的第几个元素&#xff08;按0开始编号&#xff09;&#xff0c;也可以理解为n为数组下标。 1.2、基本…

力扣刷题记录——804. 唯一摩尔斯密码词、806. 写字符串需要的行数、824. 山羊拉丁文

本专栏主要记录力扣的刷题记录&#xff0c;备战蓝桥杯&#xff0c;供复盘和优化算法使用&#xff0c;也希望给大家带来帮助&#xff0c;博主是算法小白&#xff0c;希望各位大佬不要见笑&#xff0c;今天要分享的是——《力扣刷题记录——804. 唯一摩尔斯密码词、806. 写字符串…

Apache两个解析漏洞复现及防御方法

一、多后缀解析漏洞 形成原因&#xff1a; 配置apache时&#xff0c;对于apache配置不熟练&#xff0c;配置命令不清楚&#xff0c;在配置PHP文件处理程序时&#xff0c;配置命令存在问题&#xff1a;位于漏洞环境目录的 conf/docker-php.conf里的配置命令&#xff08;AddHand…