vue-admin-template极简的 vue admin 管理后台的动态路由实现方法

news2024/9/26 3:19:13

项目源码地址:GitHub - PanJiaChen/vue-admin-template: a vue2.0 minimal admin template

注意:项目中的路由均写在 src\router\index.js 中,其中默认包含 constantRoutes 数组,这是固定路由,无论用户是什么角色,都需要显示这些路由内容(即导航栏)。

export const constantRoutes = [
    ...
]

为了根据权限来动态的生成路由,我们需要添加 asyncRoutes 数组,这里面的内容将根据用户角色权限动态生成路由内容(即导航栏)。

export const asyncRoutes = [
    ...
]

实现方法:

① 在 src\store\modules\permission.js 中,通过分析 asyncRoutes 里面的角色权限和当前用户所拥有的角色权限,生成用户可查看到的路由列表 permission_routes

② 在 src\layout\components\Sidebar\index.vue 中,遍历 permission_routes 显示菜单栏。

配置步骤

1、在 src\router\index.js 文件中

固定路由的写法,不需要任何权限,所有角色都可以访问

/**
 * 固定路由
 * 没有权限要求的基页
 * 所有角色都可以访问
 */
export const constantRoutes = [
  {
    path: '/login',
    component: () => import('@/views/login/index'),
    hidden: true
  },
  {
    path: '/404',
    component: () => import('@/views/404'),
    hidden: true
  },
  {
    path: '/dashboard',
    component: () => import('@/views/dashboard/index'),
    hidden: true
  }
  /* {
    path: '/',
    component: Layout,
    redirect: '/dashboard',
    children: [{
      path: 'dashboard',
      name: 'Dashboard',
      component: () => import('@/views/dashboard/index'),
      meta: { title: '首页' }
    }]
  } */
]

动态路由的写法,需要我们添加的地方,根据权限显示的路由

/**
 * 异步路由
 * 需要根据用户角色动态加载的路由
 */
export const asyncRoutes = [
  // 用户端 start
  {
    path: '/rescueActivity',
    redirect: '/rescueActivity',
    component: Layout,
    meta: { roles: ['user'] },
    children: [
      {
        path: '/rescueActivity',
        name: 'rescueActivity',
        component: () => import('@/views/user/rescue-activity'),
        meta: { title: '志愿救助活动' }
      }
    ]
  },
  // 用户端 end
  // 管理员端 start
  {
    path: '/userManage',
    redirect: '/userManage',
    component: Layout,
    meta: { roles: ['admin'] },
    children: [
      {
        path: '/userManage',
        name: 'userManage',
        component: () => import('@/views/admin/user-manage'),
        meta: { title: '用户管理' }
      }
    ]
  },
  // 管理员端 end
  // 404页一定要放在最后!!!
  { path: '*', redirect: '/404', hidden: true }
]

通过修改 meta 属性中 roles

只有 admin 角色可以查看:meta: { roles: ['admin'] }

admin 和 user 都可以查看:meta: { roles: ['admin', 'user'] }

注意:{ path: '*', redirect: '/404', hidden: true } 必须放在最后面,并且只能放在 asyncRoutes 中,如果放在 constantRoutes 中的话,刷新页面会报 404 错误

2、在 src\store\modules\user.js 文件中

① 在 getDefaultState 里面的 avatar: '', 后面添加 roles: [] 值,如图:

roles: []

② 在 mutations 里面的 SET_AVATAR: (state, avatar) => { state.avatar = avatar }, 后面添加 SET_ROLES: (state, roles) => { state.roles = roles } 值,如图:

SET_ROLES: (state, roles) => {
  state.roles = roles
}

③ 在 getInfo 方法里面的 commit('SET_AVATAR', avatar) 后面添加 commit('SET_ROLES', roles) 值,如图:

const { name, avatar, roles } = data
commit('SET_ROLES', roles)

④ 在 logout、resetToken 方法里面的 commit('RESET_STATE') 后面添加 commit('SET_ROLES', []) 值,如图:

commit('SET_ROLES', [])

3、添加 src\store\modules\permission.js 文件

在 src\store\modules 目录下面没有 permission.js 文件,需要添加

permission.js
import { asyncRoutes, constantRoutes } from '@/router'

/**
 * 使用 meta.role 来确定当前用户是否具有权限
 * @param roles
 * @param route
 */
function hasPermission(roles, route) {
  if (route.meta && route.meta.roles) {
    return roles.some(role => route.meta.roles.includes(role))
  } else {
    return true
  }
}

/**
 * 通过递归过滤异步路由表
 * @param routes 异步路由
 * @param roles
 */
export function filterAsyncRoutes(routes, roles) {
  const res = []
  routes.forEach(route => {
    const tmp = { ...route }
    if (hasPermission(roles, tmp)) {
      if (tmp.children) {
        tmp.children = filterAsyncRoutes(tmp.children, roles)
      }
      res.push(tmp)
    }
  })
  return res
}

const state = {
  routes: [],
  addRoutes: []
}

const mutations = {
  SET_ROUTES: (state, routes) => {
    // 这个地方维护了两个状态一个是addRouters,一个是routes
    state.addRoutes = routes
    state.routes = constantRoutes.concat(routes)
  }
}

const actions = {
  generateRoutes({ commit }, roles) {
    return new Promise(resolve => {
      const accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
      commit('SET_ROUTES', accessedRoutes)
      resolve(accessedRoutes)
    })
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}

4、在 src\store\getters.js 文件中

在 getters 里面的 name: state => state.user.name, 后面添加 roles: state => state.user.roles,  permission_routes: state => state.permission.routes 值,如图:

roles: state => state.user.roles,
permission_routes: state => state.permission.routes

5、将 src\permission.js 文件里面的内容全部替换掉

import router, { constantRoutes } from './router'
import store from './store'
import { Message } from 'element-ui'
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style
import { getToken } from '@/utils/auth' // get token from cookie
import getPageTitle from '@/utils/get-page-title'

NProgress.configure({ showSpinner: false }) // NProgress Configuration

const whiteList = ['/login'] // no redirect whitelist

router.beforeEach(async(to, from, next) => {
  // start progress bar
  NProgress.start()

  // set page title
  document.title = getPageTitle(to.meta.title)

  // determine whether the user has logged in
  const hasToken = getToken()

  if (hasToken) {
    if (to.path === '/login') {
      // if is logged in, redirect to the home page
      next({ path: '/' })
      NProgress.done()
    } else {
      const hasRoles = store.getters.roles && store.getters.roles.length > 0
      if (hasRoles) {
        next()
      } else {
        try {
          // get user info
          // note: roles must be a object array! such as: ['admin'] or ,['developer','editor']
          const { roles } = await store.dispatch('user/getInfo')
          // generate accessible routes map based on roles
          const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
          // dynamically add accessible routes
          router.options.routes = constantRoutes.concat(accessRoutes)
          router.addRoutes(accessRoutes)

          // hack method to ensure that addRoutes is complete
          // set the replace: true, so the navigation will not leave a history record
          next({ ...to, replace: true })
        } catch (error) {
          // remove token and go to login page to re-login
          await store.dispatch('user/resetToken')
          Message.error(error || 'Has Error')
          next(`/login?redirect=${to.path}`)
          NProgress.done()
        }
      }
    }
  } else {
    /* has no token*/

    if (whiteList.indexOf(to.path) !== -1) {
      // in the free login whitelist, go directly
      next()
    } else {
      // other pages that do not have permission to access are redirected to the login page.
      next(`/login?redirect=${to.path}`)
      NProgress.done()
    }
  }
})

router.afterEach(() => {
  // finish progress bar
  NProgress.done()
})

6、在 src\layout\components\Sidebar\index.vue 文件中

将原来的 <sidebar-item ... /> 替换掉

<sidebar-item v-for="route in permission_routes" :key="route.path" :item="route" :base-path="route.path" />

在 ...mapGetters 里面的 'sidebar', 后面添加 'permission_routes' 值,如图:

'permission_routes'

7、在 src\store\index.js 文件中

import user from './modules/user' 下面添加 import permission from './modules/permission' 导入 permission 值;在 new Vuex.Store 里面的 user, 后面添加 permission 值,如图:

import permission from './modules/permission'
permission

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

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

相关文章

数据结构从入门到精通——冒泡排序

冒泡排序 前言一、冒泡排序的基本思想二、冒泡排序的特性总结三、冒泡排序的动画演示四、冒泡排序的具体代码test.c 前言 冒泡排序是一种简单的排序算法&#xff0c;通过重复遍历待排序数列&#xff0c;比较相邻元素的大小并交换位置&#xff0c;使得每一轮遍历后最大&#xf…

ubuntu内存不足,用Swap扩展增加虚拟内存

Linux增大Swap分区&#xff0c;可以增加虚拟内存&#xff0c;以解决电脑卡机&#xff0c;内存不足等问题 top可以查看cpu的使用情况 lscpu可以查看本机配置的cpu硬件情况 查看内存使用情况 free -h (下面显示"交换"或者Swap等字样说明系统已经启动了Swap&#xff…

EMC Unity存储系统(包含VNXe)常用检查命令

DELL EMC的Unity存储系统&#xff0c;包括VNXe存储系统的OS已经完全和Clariion 的VNX不同了&#xff0c;近期遇到很多关于EMC unity存储系统故障的一些初步检查需求&#xff0c;下面是一些对于DELL EMC Unity存储系统的最常用的底层检查命令&#xff0c;可以对系统故障有个初步…

深度学习——线性代数相关知识

线性代数基础知识 一、线性代数基础知识1、标量2、向量3、矩阵4、张量5、点积6、向量—矩阵积7、矩阵—矩阵乘法 二、小结 一、线性代数基础知识 本节将介绍简要地回顾一下部分基本线性代数内容&#xff0c;线性代数中的基本数学对象、算术和运算&#xff0c;并用数学符号和相…

Linux编程4.11 网络编程-广播

广播实现一对多的通讯 它通过向广播地址发送数据报文实现的 1、套接字选项 套接字选项用于修饰套接字以及其底层通讯协议的各种行为。函数setsockopt和getsockopt可以查看和设置套接字的各种选项。 #include <sys/types.h> #include <sys/socket.h>int getso…

申请免费IP地址证书

目录 IP申请SSL证书需要满足什么条件呢&#xff1f; 为什么需要申请IP地址证书&#xff1f; 支持IP地址SSL证书类型 DV级别IP SSL证书和OV级别IP SSL证书的区别 申请公网IP地址证书有免费的吗&#xff1f; 背景&#xff1a;当用户直接通过IP地址而非域名访问网站时&#xf…

后端如何返回404地址

当我们网站输入不存在的地址&#xff0c;经常会出现404的页面&#xff0c;这是如何做到的 1.添加配置 spring:mvc:view:prefix: /templates/suffix: .html 2.resources下添加templates目录&#xff0c;下面放404的网站 3.添加依赖&#xff0c;版本在主pom里面配置好了&#x…

霍格沃兹测试开发从人员外包到测试工具、测试平台,提供全方位的测试解决方案~

随着学社的学员越来越多&#xff0c;影响力越来越大&#xff0c;不停有学员和企业问我们&#xff1a;能否提供人员外包服务&#xff1f;与此同时&#xff0c;企业对于外包人员的业务技能要求也越来越高&#xff0c;寻找一个稳定靠谱的供应商也成了很多学员所在公司的需求。对此…

web前端常用标签(html)

1.定义 1.1标签 语法规范&#xff1a;<标签名 属性名"属性值">标签名</标签名> 标签之间可以嵌套 1.2属性 定制元素的行为的。属性是不通用的&#xff0c;每一个标签存在自身的属性。当属性名属性值时&#xff0c;可以只写属性值 2.HTML常用标签 2…

【人工智能Ⅱ】实验2:VGG图像分类

实验2&#xff1a;VGG图像分类 一&#xff1a;实验目的与要求 1&#xff1a;掌握VGG网络的原理与结构。 2&#xff1a;学会利用VGG网络建立训练模型&#xff0c;并对模型进行评估。 3&#xff1a;学会使用VGG网络进行分类。 二&#xff1a;实验内容 1&#xff1a;用VGG网络…

扩展欧拉定理

为了求a^bmodm的余数,我们可以利用扩展欧拉定理给出的同余方程,转化成一个好求的式子,首先我们要能够解出欧拉函数.欧拉函数讲解可以看看这篇欧拉函数最全总结-CSDN博客(原理我不懂,只会用) 下面给出代码 using i64 long long; int phi(int n) {int res n;for (int i 2; i…

【C语言】内存管理内存管理函数文件管理文件管理函数

主页&#xff1a;醋溜马桶圈-CSDN博客 专栏&#xff1a;C语言_醋溜马桶圈的博客-CSDN博客 gitee&#xff1a;mnxcc (mnxcc) - Gitee.com 目录 1.C/C程序的内存开辟 2.内存相关的函数 2.1 memcpy 2.1.1 memcpy函数的使用 2.1.2 memcpy函数的模拟实现 2.2 memmove 2.2.2 me…

四阶Runge-Kutta方法求解高阶微分方程

一、经典的Runge-Kutta方法&#xff08;四级四阶RK方法&#xff09; Runge-Kutta法&#xff08;简写为RK方法&#xff09;既可达到较高精度&#xff0c;又可避免高阶导数计算。 对微分方程,在区间上的四阶Runge-Kutta方法的公式如下&#xff1a; 二、利用4阶Runge-Kutta方法计…

Elasticsearch - Docker安装Elasticsearch8.12.2

前言 最近在学习 ES&#xff0c;所以需要在服务器上装一个单节点的 ES 服务器环境&#xff1a;centos 7.9 安装 下载镜像 目前最新版本是 8.12.2 docker pull docker.elastic.co/elasticsearch/elasticsearch:8.12.2创建配置 新增配置文件 elasticsearch.yml http.host…

.locked勒索病毒是什么,企业数据被加密了如何恢复?

.locked勒索病毒介绍 .locked勒索病毒是一种恶意软件&#xff0c;它利用加密技术锁定用户的数据或系统&#xff0c;并以此进行勒索。用户一旦感染此病毒&#xff0c;将无法访问其重要文件&#xff0c;病毒会要求用户支付一笔赎金以获取解密密钥。这种病毒通常使用强大的加密算法…

为什么选VR全景技术进行乡村展示,VR全景技术助力乡村振兴

引言&#xff1a; 在科技飞速发展的当下&#xff0c;乡村振兴成为国家重要战略&#xff0c;如何创新性地展示乡村特色&#xff0c;提升乡村吸引力&#xff0c;成为当务之急。VR全景技术&#xff0c;作为一种新兴的展示手段&#xff0c;可以为乡村展示提供全新的视角&#xff0…

可观测性体系建设后,该如何挖掘数据及工具价值?

在现代企业的运维管理中&#xff0c;构建高效且可靠的可观测性体系是保障系统稳定性和业务连续性的关键。然而&#xff0c;运维团队成员的技术能力参差不齐往往成为实现这一目标的障碍。尤其在处理复杂系统故障时&#xff0c;高度依赖专业知识和经验的可观测性工具很难被全员有…

如何在Linux Ubuntu系统安装Nginx服务并实现无公网IP远程连接

文章目录 1. 安装Docker2. 使用Docker拉取Nginx镜像3. 创建并启动Nginx容器4. 本地连接测试5. 公网远程访问本地Nginx5.1 内网穿透工具安装5.2 创建远程连接公网地址5.3 使用固定公网地址远程访问 在开发人员的工作中&#xff0c;公网远程访问内网是其必备的技术需求之一。对于…

vue key的bug

今天遇到一个bug&#xff0c;列表删除元素时&#xff0c;明明在外层设置了key&#xff0c;但是列表元素的状态居然复用了&#xff0c;找了好久原因&#xff0c;最后是key的取值问题&#xff0c;记录一下。 首先key可以取undefine&#xff0c;这个是不会报错的 然后项目的代码结…

C#配置连接数据库字段

在Web.config文件中 添加如下配置 <!--连接数据库字段--><connectionStrings><add name"sql" connectionString"server.;uidsa;pwd8888;databaseArticleWebSite" /></connectionStrings>