当前位置: 首页 > news >正文

Vue核心知识:Vue动态权限到按钮完整方案

为了进一步实现上面提到的动态路由功能,并且加入对每个路由的权限控制(即增、删、改、查按钮的权限控制),我们需要对数据库、后端接口、前端的设计做一些改进和扩展。下面我将详细描述如何在现有方案的基础上加入对路由的增、删、改、查权限控制。

目录

      • 一、数据库设计扩展
        • 1.1 修改路由表(routes)
        • 1.2 修改角色与路由权限表(role_routes)
      • 二、后端接口设计
        • 2.1 修改获取路由接口
        • 2.2 添加路由权限的接口
      • 三、前端实现
        • 3.1 动态生成路由
        • 3.2 根据权限动态显示按钮
        • 3.3 在Vuex中存储用户权限
      • 四、总结

一、数据库设计扩展

为了实现更细粒度的权限控制,我们需要对数据库结构做一些修改和扩展,增加对路由权限的支持。每个路由会关联四个权限:增、删、改、查。

1.1 修改路由表(routes)

首先,我们要扩展路由表,使其支持每个路由的增、删、改、查权限。

CREATE TABLE routes (
    id INT AUTO_INCREMENT PRIMARY KEY,
    path VARCHAR(255) NOT NULL,
    component VARCHAR(255) NOT NULL,
    name VARCHAR(255) NOT NULL,
    parent_id INT DEFAULT 0,
    meta JSON DEFAULT NULL, 
    is_enabled BOOLEAN DEFAULT TRUE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    -- 增、删、改、查权限
    permission_create BOOLEAN DEFAULT FALSE,
    permission_delete BOOLEAN DEFAULT FALSE,
    permission_update BOOLEAN DEFAULT FALSE,
    permission_view BOOLEAN DEFAULT TRUE
);
  • permission_create:该路由是否具有增权限。
  • permission_delete:该路由是否具有删权限。
  • permission_update:该路由是否具有改权限。
  • permission_view:该路由是否具有查权限。
1.2 修改角色与路由权限表(role_routes)

role_routes表中,新增字段来存储角色对路由的权限,分别对应增、删、改、查。

CREATE TABLE role_routes (
    role_id INT,
    route_id INT,
    permission_create BOOLEAN DEFAULT FALSE,
    permission_delete BOOLEAN DEFAULT FALSE,
    permission_update BOOLEAN DEFAULT FALSE,
    permission_view BOOLEAN DEFAULT TRUE,
    PRIMARY KEY (role_id, route_id),
    FOREIGN KEY (role_id) REFERENCES roles(id),
    FOREIGN KEY (route_id) REFERENCES routes(id)
);
  • 每条记录表示角色对某个路由的权限。

二、后端接口设计

在后端,我们需要确保路由的增、删、改、查权限在获取路由数据时被正确地返回,并且在路由的操作(如添加、删除、修改、查看)时进行权限控制。

2.1 修改获取路由接口

修改/api/get_routes接口,增加对路由权限的支持,返回每个路由的增、删、改、查权限信息。

@app.route('/api/get_routes', methods=['GET'])
def get_routes():
    role_name = request.args.get('role')
    role = Role.query.filter_by(name=role_name).first()
    
    if not role:
        return jsonify({'message': 'Role not found'}), 404
    
    routes = db.session.query(Route).join(RoleRoute).filter(RoleRoute.role_id == role.id).all()
    routes_data = []
    
    for route in routes:
        role_route = RoleRoute.query.filter_by(role_id=role.id, route_id=route.id).first()
        routes_data.append({
            'path': route.path,
            'component': route.component,
            'name': route.name,
            'meta': route.meta,
            'permissions': {
                'create': role_route.permission_create,
                'delete': role_route.permission_delete,
                'update': role_route.permission_update,
                'view': role_route.permission_view
            }
        })
    
    return jsonify(routes_data)

在这个接口中,我们通过RoleRoute表来获取每个角色对应的路由权限,并将这些权限一起返回。

2.2 添加路由权限的接口

我们还需要提供一个接口来修改路由权限(即为角色设置增、删、改、查权限)。

@app.route('/api/set_route_permissions', methods=['POST'])
def set_route_permissions():
    data = request.json
    role_id = data['role_id']
    route_id = data['route_id']
    permission_create = data['permission_create']
    permission_delete = data['permission_delete']
    permission_update = data['permission_update']
    permission_view = data['permission_view']

    role_route = RoleRoute.query.filter_by(role_id=role_id, route_id=route_id).first()

    if not role_route:
        role_route = RoleRoute(role_id=role_id, route_id=route_id)
        db.session.add(role_route)

    role_route.permission_create = permission_create
    role_route.permission_delete = permission_delete
    role_route.permission_update = permission_update
    role_route.permission_view = permission_view
    
    db.session.commit()

    return jsonify({'message': 'Permissions updated successfully'})

该接口接收角色ID、路由ID以及增、删、改、查权限的设置,并更新数据库中的权限数据。

三、前端实现

前端需要根据从后端接口获取的路由信息和权限数据,动态生成路由,并根据权限来控制不同路由下按钮的显示与操作权限。

3.1 动态生成路由

前端的路由配置需要动态加载,并在路由生成时判断当前用户对该路由的权限。

router/index.js中,我们可以根据权限信息来配置动态路由。

import Vue from 'vue';
import Router from 'vue-router';
import store from '../store';

Vue.use(Router);

const router = new Router({
  routes: []
});

function generateRoutes(routes) {
  const routeArray = [];
  routes.forEach(route => {
    const routeConfig = {
      path: route.path,
      name: route.name,
      component: () => import(`@/views/${route.component}.vue`), // 动态加载组件
      meta: route.meta,
      permissions: route.permissions // 保存权限数据
    };

    if (route.children && route.children.length > 0) {
      routeConfig.children = generateRoutes(route.children);
    }

    routeArray.push(routeConfig);
  });
  return routeArray;
}

router.beforeEach(async (to, from, next) => {
  if (!store.state.routes.length) {
    const res = await store.dispatch('getRoutes');
    const routes = generateRoutes(res);
    routes.forEach(route => {
      router.addRoute(route);
    });
    next({ ...to, replace: true });
  } else {
    next();
  }
});

export default router;
3.2 根据权限动态显示按钮

前端页面上的操作按钮(如增、删、改、查)需要根据用户对路由的权限来进行显示和隐藏。假设每个页面都有这些按钮,我们可以使用v-if指令来根据权限控制显示与否。

<template>
  <div>
    <button v-if="hasCreatePermission">新增</button>
    <button v-if="hasUpdatePermission">编辑</button>
    <button v-if="hasDeletePermission">删除</button>
    <button v-if="hasViewPermission">查看</button>
  </div>
</template>

<script>
export default {
  computed: {
    hasCreatePermission() {
      return this.$store.state.userPermissions.create;
    },
    hasUpdatePermission() {
      return this.$store.state.userPermissions.update;
    },
    hasDeletePermission() {
      return this.$store.state.userPermissions.delete;
    },
    hasViewPermission() {
      return this.$store.state.userPermissions.view;
    }
  },
  created() {
    this.setPermissions(this.$route.meta.permissions);
  },
  methods: {
    setPermissions(permissions) {
      this.$store.commit('setUserPermissions', permissions);
    }
  }
}
</script>

在这个组件中,我们使用v-if指令根据权限来显示对应的按钮。hasCreatePermissionhasUpdatePermission等计算属性返回当前用户对该页面的权限,setPermissions方法会在页面加载时设置当前用户的权限。

3.3 在Vuex中存储用户权限

在Vuex中,我们可以存储用户的权限数据,并在不同的组件中访问。

// store.js
export default new Vuex.Store({
  state: {
    userPermissions: {
      create: false,
      delete: false,
      update: false,
      view: true
    }
  },
  mutations: {
    setUserPermissions(state, permissions) {
      state.userPermissions = permissions;
    }
  },
  actions: {
    async getRoutes({ commit }) {
      const res = await axios.get('/api/get_routes', { params: { role: 'admin' } });
      commit('setRoutes', res.data);
      return res.data;
    }
  }
});

四、总结

通过以上的设计和实现,我们能够在前端根据路由和权限动态生成路由,并且为每个路由设置增、删、改、查等操作的权限。后端负责根据用户的角色返回对应的权限信息,前端通过vue-routervuex管理动态路由和用户权限。通过这种方式,系统可以灵活地根据角色和权限来展示不同的功能,并且有效地控制用户对数据的操作权限。

这种设计方式非常适合复杂权限管理的系统,能够提供细粒度的权限控制,并且可以随着业务需求的变化灵活调整。
在这里插入图片描述

相关文章:

  • 【SpringCloud】Gateway
  • Llama 2中的Margin Loss:为何更高的Margin导致更大的Loss和梯度?
  • 【Spring】配置文件的使用
  • Windows 上通过 VScode 配置 Docker
  • 如何修改电脑mac地址?
  • 利用 LangChain 和一个大语言模型(LLM)构建一个链条,自动从用户输入的问题中提取相关的 SQL 表信息,再生成对应的 SQL 查询
  • 360个人版和企业版的区别
  • 在C++中如何实现线程安全的队列
  • Qt:窗口
  • CAN总线通信协议学习2——数据链路层之帧格式
  • 【Linux】TCP协议
  • 名词解释:vllm,大模型量化;以及如何在vllm实现大模型量化
  • Vue 系列之:基础知识
  • Java-servlet(二)Java-servlet-Web环境搭建(上)IDEA,maven和tomcat工具下载(附Gitee直接下载)
  • 现今大语言模型性能(准确率)比较
  • 《论企业集成架构设计及应用》审题技巧 - 系统架构设计师
  • 在Ubuntu 22.04 LTS 上安装 MySQL两种方式:在线方式和离线方式
  • 基于Java的AI应用开发实战:从模型训练到服务部署
  • 中间件专栏之Redis篇——Redis的基本IO网络模型
  • 每日OJ_牛客_NC316体育课测验(二)_拓扑排序_C++_Java
  • 新四军老战士、苏州市文联原副主席张景坤逝世
  • 北京人艺新戏《一日顶流》将出现人工智能角色
  • 申伟强任上海申通地铁集团有限公司副总裁
  • 王毅同德国外长瓦德富尔通电话
  • 去年上海60岁及以上户籍老年人口占总人口的37.6%
  • 上海肺科医院院长陈昶:临床中的痛点,正是新技术诞生的起点