vue后台管理系统实现权限控制(逻辑)

1.vuex中定义一个用户状态,roles储存当前登录用户的权限

在这里插入图片描述
写一个存储roles的mutations

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

2.登录时,查询用户的状态,再将权限状态存储。写一个ations

    // 获取用户信息
    actions:{
        GetUserInfo({ commit, state }) {
      return new Promise((resolve, reject) => {
        // getUserInfo 获取用户信息接口 
        getUserInfo(state.token).then(response => {
          if (!response.data) {
            reject('error')
          }
          const data = response.data
          if (data.roles && data.roles.length > 0) { // 验证返回的roles是否是一个非空数组
            commit('SET_ROLES', data.roles) // 此处储存权限
          } else {
            reject('getInfo: roles must be a non-null array !')
          }
          resolve(response)
        }).catch(error => {
          reject(error)
        })
      })
    },
    }

3. 在router中编写公共路由表(constantRouterMap)和动态路由表(asyncRouterMap),利用route中的meta属性储存该路由的权限信息

例:

export const constantRouterMap = [
  { path: '/login', component: () => import('@/views/login/index'), hidden: true },
  { path: '/404', component: () => import('@/views/errorPage/404'), hidden: true },
  { path: '/401', component: () => import('@/views/errorPage/401'), hidden: true },
]
// account路由权限 ['super-admin', 'admin'],/account/account-admin路由权限['admin']
export const asyncRouterMap = [
  {
    path: '/account',
    meta: {  roles: ['super-admin', 'admin'] },
    children: [
      { path: '/account-admin', component: () => import('组件路径'), name: 'account', meta: { roles: ['admin'] } },
    ]
  },
]

4. vuex中编写权限处理permission.js

// 导入 公共和动态路由表
import { asyncRouterMap, constantRouterMap } from '@/router'

/**
 * 通过meta.role判断是否与当前用户权限匹配
 * @param roles
 * @param route
 */
 // 判断当前路由中的权限 route.meta.roles 是否包括登录用户的权限
 // 例 该/account路由权限['super-admin', 'admin']  登录用户为['admin'] 返回true
function hasPermission(roles, route) {
  if (route.meta && route.meta.roles) {
    return roles.some(role => route.meta.roles.indexOf(role) >= 0)
  } else {
    return true
  }
}

/**
 * 递归过滤异步路由表,返回符合用户角色权限的路由表
 * @param asyncRouterMap
 * @param roles 当前登录的用户权限  格式例:['admin']
 */
function filterAsyncRouter(asyncRouterMap, roles) {
  const accessedRouters = asyncRouterMap.filter(route => {
    if (hasPermission(roles, route)) {
      if (route.children && route.children.length) {
        route.children = filterAsyncRouter(route.children, roles)
      }
      return true
    }
    return false
  })
  return accessedRouters
}

const permission = {
  state: {
    routers: constantRouterMap,
    addRouters: []
  },
  mutations: {
    // 将过滤好的动态路由与公共路由合并,生成最终的路由表
    SET_ROUTERS: (state, routers) => {
      state.addRouters = routers
      state.routers = constantRouterMap.concat(routers)
    }
  },
  actions: {
    GenerateRoutes({ commit }, data) {
      return new Promise(resolve => {
        const { roles } = data
        let accessedRouters
        // 超级管理员拥有所有权限 直接合并公共路由和动态路由表
        if (roles.indexOf('super-admin') >= 0) {
          accessedRouters = asyncRouterMap
        } else {
          accessedRouters = filterAsyncRouter(asyncRouterMap, roles)
        }
        commit('SET_ROUTERS', accessedRouters)
        resolve()
      })
    }
  }
}

export default permission

5. 在main.js同级目录创建一个权限处理js

import router from './router'
import store from './store'
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css'// progress bar style
import { getToken } from '@/utils/auth' // getToken from cookie

NProgress.configure({ showSpinner: false })// NProgress Configuration
const whiteList = ['/login', '/bhp']// no redirect whitelist

router.beforeEach((to, from, next) => {
  NProgress.start() // start progress bar
  if (getToken()) { // determine if there has token
    /* has token*/
    if (to.path === '/login') {
      next({ path: '/' })
      NProgress.done() // if current page is dashboard will not trigger	afterEach hook, so manually handle it
    } else {
      if (store.getters.roles.length === 0) { // 判断当前用户是否已拉取完user_info信息
        store.dispatch('GetUserInfo').then(res => { // 拉取user_info 用户信息
          const roles = res.data.roles // note: roles must be a array! such as: ['super-admin','admin']
          // 此处调用4中的vuex方法 将用户权限传入
          store.dispatch('GenerateRoutes', { roles }).then(() => {
          //最终的路由表通过addRoutes,加入到router中
            router.addRoutes(store.getters.addRouters)
            next({ ...to, replace: true })
          })
        }).catch(() => {
          store.dispatch('FedLogOut').then(() => {
            // Message.error(err || 'Verification failed, please login again')
            next({ path: '/' })
          })
        })
      } else {
        next()
      }
    }
  } else {
    /* has no token*/
    if (whiteList.indexOf(to.path) !== -1) { // 在免登录白名单,直接进入
      next()
    } else {
      next('/login') // 否则全部重定向到登录页
      NProgress.done() // if current page is login will not trigger afterEach hook, so manually handle it
    }
  }
})
router.afterEach(() => {
  NProgress.done() // finish progress bar
})

6.在main.js中导入5中的同级权限js

import './permission' // permission control

7. 在el-menu菜单中,判断动态生成子菜单

此处的routes来自4中,vuex中permission.js中的status.routers

<template v-for="item in routes" v-if="!item.hidden&&item.children">
  <router-link
    v-if="hasOneShowingChildren(item.children) && !item.children[0].children&&!item.alwaysShow"
    :to="item.path+'/'+item.children[0].path"
    :key="item.children[0].name"
  >
    <el-menu-item
      :index="item.path+'/'+item.children[0].path"
      :class="{'submenu-title-noDropdown':!isNest}"
    >
    </el-menu-item>
  </router-link>

  <el-submenu v-else :index="item.name||item.path" :key="item.name">
    <template slot="title">
      <svg-icon v-if="item.meta&&item.meta.icon" :icon-class="item.meta.icon"></svg-icon>
      <span v-if="item.meta&&item.meta.title" slot="title">{{generateTitle(item.meta.title)}}</span>
    </template>

    <template v-for="child in item.children" v-if="!child.hidden">
      <sidebar-item
        :is-nest="true"
        class="nest-menu"
        v-if="child.children&&child.children.length>0"
        :routes="[child]"
        :key="child.path"
      ></sidebar-item>

      <router-link v-else :to="item.path+'/'+child.path" :key="child.name">
        <el-menu-item :index="item.path+'/'+child.path" @click="clickSideBar">
        </el-menu-item>
      </router-link>
    </template>
  </el-submenu>
</template>
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
后台管理系统中,权限分为功能级权限和数据级权限。功能级权限是指用户在系统中可以执行的具体功能,如增删改查等。而数据级权限则是指用户对数据的操作权限,比如某个用户只能查看自己的数据而不能查看其他用户的数据。 在Vue 3的后台管理系统中,一般会通过后端返回功能权限的方式来实现权限控制。登录成功后,后端会返回功能权限,最好是路由配置的形式,前端可以把功能权限处理成路由配置的JSON数组格式。然后使用`vue-router`对象的`addRoutes`方法将该路由配置动态添加到路由对象中。同时,为了防止前端刷新后丢失路由配置,可以将该路由配置保存到`sessionStorage`中。 以下是一个实现的示例代码: ```javascript // 默认路由配置里只有登录的配置 import Vue from 'vue'; import VueRouter from "vue-router"; import Login from "@/pages/Login"; Vue.use(VueRouter); // 安装vue-router到Vue // 创建vue-router对象 let router = new VueRouter({ mode: "hash", // 路由模式 routes: [ { path: "/", redirect: "/Login" }, { path: "/Login", component: Login } ] }); export default router; ``` 在登录成功后,可以使用`axios`等库向后端发送请求,获取到用户的权限信息。然后根据后端返回的权限,生成该用户对应的路由配置。通过过滤所有路由配置,只保留用户有权限访问的路由配置,得到`currRoutes`。然后将获取到的权限保存到`sessionStorage`中,并将获取到的权限动态添加到`vue-router`对象中。最后,使用`this.$router.push("/Home")`跳转到首页或指定页面。 请注意,这只是一个示例代码,实际的权限控制可能需要更多的细节和逻辑处理。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [后台管理系统权限以及vue处理权限的思路](https://blog.csdn.net/sdasadasds/article/details/126665717)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值