当前位置:首页 > 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中,与路由表保持同步。

vue 实现权限管理

// 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状态码统一跳转到无权限页面。

vue 实现权限管理

// 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 实现简单登陆

以下是一个使用 Vue 3 实现的简单登录功能示例,包含表单验证和基础交互逻辑: 创建 Vue 组件 <template> <div class="login-contai…

vue实现新闻

vue实现新闻

Vue 实现新闻功能 使用 Vue 实现新闻功能通常涉及新闻列表展示、新闻详情页、分类筛选等模块。以下是实现的基本思路和代码示例。 新闻列表展示 通过 Vue 组件展示新闻列表,通常使用 v-for…

vue实现数组

vue实现数组

Vue 实现数组操作的方法 在 Vue 中,数组的操作需要特别注意响应式的问题。Vue 提供了一些方法来确保数组的变动能够触发视图更新。 响应式数组方法 Vue 对以下数组方法进行了封装,确保它们能…

vue实现slidetoggle

vue实现slidetoggle

Vue 实现 SlideToggle 效果 SlideToggle 是一种常见的交互效果,元素以滑动方式展开或收起。以下是几种实现方法: 使用 CSS Transition 和 v-show…

vue实现视频

vue实现视频

Vue 实现视频播放的方法 在 Vue 项目中实现视频播放可以通过多种方式完成,以下是几种常见的方法: 使用 HTML5 的 <video> 标签 在 Vue 组件中直接使用 HTML…

vue首页实现

vue首页实现

实现Vue首页的基本步骤 创建一个Vue首页通常涉及项目初始化、页面结构设计、路由配置和组件开发。以下是具体实现方法: 初始化Vue项目 使用Vue CLI或Vite快速搭建项目结构: npm i…