当前位置:首页 > VUE

vue 实现权限管理

2026-02-18 14:32:04VUE

路由权限控制

使用Vue Router的beforeEach钩子进行路由拦截,结合用户角色动态过滤路由表。初始化时只加载基础路由,登录后根据角色动态添加可访问路由。

// router.js
const createRouter = () => new Router({
  routes: constantRoutes // 基础路由
})

router.beforeEach(async (to, from, next) => {
  const hasToken = getToken()
  if (hasToken) {
    if (to.path === '/login') {
      next({ path: '/' })
    } else {
      const hasRoles = store.getters.roles.length > 0
      if (hasRoles) {
        next()
      } else {
        try {
          const { roles } = await store.dispatch('user/getInfo')
          const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
          router.addRoutes(accessRoutes)
          next({ ...to, replace: true })
        } catch (error) {
          await store.dispatch('user/resetToken')
          next(`/login?redirect=${to.path}`)
        }
      }
    }
  } else {
    if (whiteList.includes(to.path)) {
      next()
    } else {
      next(`/login?redirect=${to.path}`)
    }
  }
})

动态菜单生成

基于权限路由自动生成侧边栏菜单,使用递归组件渲染多级菜单结构。菜单数据建议存储在Vuex中,与路由表保持同步。

// store/modules/permission.js
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
}

按钮级权限控制

通过自定义指令v-permission实现按钮粒度的权限控制,没有权限的按钮会被自动移除或禁用。

// directives/permission.js
export default {
  inserted(el, binding, vnode) {
    const { value } = binding
    const roles = store.getters.roles
    if (value && value instanceof Array) {
      const permissionRoles = value
      const hasPermission = roles.some(role => {
        return permissionRoles.includes(role)
      })
      if (!hasPermission) {
        el.parentNode && el.parentNode.removeChild(el)
      }
    } else {
      throw new Error(`需要指定权限数组`)
    }
  }
}

API请求鉴权

在axios拦截器中自动携带token,后端接口根据token进行权限验证。对于403状态码统一跳转到无权限页面。

// utils/request.js
service.interceptors.request.use(
  config => {
    if (store.getters.token) {
      config.headers['Authorization'] = `Bearer ${getToken()}`
    }
    return config
  },
  error => {
    return Promise.reject(error)
  }
)

service.interceptors.response.use(
  response => {
    const res = response.data
    if (res.code !== 200) {
      if (res.code === 403) {
        MessageBox.confirm('权限不足', '提示', {
          type: 'warning'
        })
      }
      return Promise.reject(new Error(res.message || 'Error'))
    } else {
      return res
    }
  }
)

权限数据持久化

使用vuex-persistedstate插件将权限数据持久化到localStorage,避免刷新后丢失权限状态。敏感数据建议加密存储。

// store/index.js
import createPersistedState from 'vuex-persistedstate'
export default new Vuex.Store({
  plugins: [
    createPersistedState({
      key: 'auth',
      paths: ['user.token', 'user.roles']
    })
  ]
})

服务端权限校验

前端权限控制只是用户体验优化,必须在服务端进行最终权限验证。RBAC模型是常见解决方案,包含用户-角色-权限三层关系。

-- 数据库表结构示例
CREATE TABLE `sys_user` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `username` varchar(50) NOT NULL,
  `password` varchar(100) NOT NULL
);

CREATE TABLE `sys_role` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL
);

CREATE TABLE `sys_permission` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `perm` varchar(50) NOT NULL,
  `description` varchar(100) DEFAULT NULL
);

vue 实现权限管理

标签: 权限vue
分享给朋友:

相关文章

vue实现tab换行

vue实现tab换行

Vue实现Tab切换的常见方法 使用Vue实现Tab切换功能可以通过多种方式完成,以下是几种常见的方法: 动态组件结合v-if或v-show 通过v-if或v-show控制不同Tab内容的显示…

vue卖座网实现

vue卖座网实现

Vue 卖座网实现 项目结构搭建 使用 Vue CLI 快速初始化项目,安装必要依赖如 Vue Router、Vuex、Axios。 创建核心目录结构:components(通用组件)、views(页…

vue手写签名如何实现

vue手写签名如何实现

实现手写签名的基本思路 在Vue中实现手写签名功能,通常需要借助HTML5的Canvas API来捕获用户的绘制操作。核心流程包括初始化画布、监听触摸/鼠标事件、记录轨迹以及生成签名图片。 安装依…

vue实现框架

vue实现框架

Vue 框架实现的核心方法 基础项目搭建 使用 Vue CLI 或 Vite 快速初始化项目。Vue CLI 适合传统项目,Vite 更适合现代轻量级应用。安装后通过命令行工具选择所需配置(如 Rou…

vue 实现直播

vue 实现直播

Vue 实现直播的基本方法 在Vue中实现直播功能,通常需要结合WebRTC、RTMP或HLS等技术。以下是几种常见的实现方式: 使用WebRTC实现实时直播 WebRTC适合低延迟的实时直播场景,…

vue 实现视频

vue 实现视频

Vue 实现视频播放功能 使用 Vue 实现视频播放功能可以通过 HTML5 的 <video> 标签或第三方库(如 video.js)来实现。以下是两种常见的方法: 使用 HTML5…