Vue中動(dòng)態(tài)權(quán)限到按鈕的完整實(shí)現(xiàn)方案詳解
為了進(jìn)一步實(shí)現(xiàn)上面提到的動(dòng)態(tài)路由功能,并且加入對每個(gè)路由的權(quán)限控制(即增、刪、改、查按鈕的權(quán)限控制),我們需要對數(shù)據(jù)庫、后端接口、前端的設(shè)計(jì)做一些改進(jìn)和擴(kuò)展。下面我將詳細(xì)描述如何在現(xiàn)有方案的基礎(chǔ)上加入對路由的增、刪、改、查權(quán)限控制。
一、數(shù)據(jù)庫設(shè)計(jì)擴(kuò)展
為了實(shí)現(xiàn)更細(xì)粒度的權(quán)限控制,我們需要對數(shù)據(jù)庫結(jié)構(gòu)做一些修改和擴(kuò)展,增加對路由權(quán)限的支持。每個(gè)路由會(huì)關(guān)聯(lián)四個(gè)權(quán)限:增、刪、改、查。
1.1 修改路由表(routes)
首先,我們要擴(kuò)展路由表,使其支持每個(gè)路由的增、刪、改、查權(quán)限。
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, -- 增、刪、改、查權(quán)限 permission_create BOOLEAN DEFAULT FALSE, permission_delete BOOLEAN DEFAULT FALSE, permission_update BOOLEAN DEFAULT FALSE, permission_view BOOLEAN DEFAULT TRUE );
- permission_create:該路由是否具有增權(quán)限。
- permission_delete:該路由是否具有刪權(quán)限。
- permission_update:該路由是否具有改權(quán)限。
- permission_view:該路由是否具有查權(quán)限。
1.2 修改角色與路由權(quán)限表(role_routes)
在role_routes表中,新增字段來存儲(chǔ)角色對路由的權(quán)限,分別對應(yīng)增、刪、改、查。
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) );
每條記錄表示角色對某個(gè)路由的權(quán)限。
二、后端接口設(shè)計(jì)
在后端,我們需要確保路由的增、刪、改、查權(quán)限在獲取路由數(shù)據(jù)時(shí)被正確地返回,并且在路由的操作(如添加、刪除、修改、查看)時(shí)進(jìn)行權(quán)限控制。
2.1 修改獲取路由接口
修改/api/get_routes接口,增加對路由權(quán)限的支持,返回每個(gè)路由的增、刪、改、查權(quán)限信息。
@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)
在這個(gè)接口中,我們通過RoleRoute表來獲取每個(gè)角色對應(yīng)的路由權(quán)限,并將這些權(quán)限一起返回。
2.2 添加路由權(quán)限的接口
我們還需要提供一個(gè)接口來修改路由權(quán)限(即為角色設(shè)置增、刪、改、查權(quán)限)。
@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'})
該接口接收角色I(xiàn)D、路由ID以及增、刪、改、查權(quán)限的設(shè)置,并更新數(shù)據(jù)庫中的權(quán)限數(shù)據(jù)。
三、前端實(shí)現(xiàn)
前端需要根據(jù)從后端接口獲取的路由信息和權(quán)限數(shù)據(jù),動(dòng)態(tài)生成路由,并根據(jù)權(quán)限來控制不同路由下按鈕的顯示與操作權(quán)限。
3.1 動(dòng)態(tài)生成路由
前端的路由配置需要?jiǎng)討B(tài)加載,并在路由生成時(shí)判斷當(dāng)前用戶對該路由的權(quán)限。
在router/index.js中,我們可以根據(jù)權(quán)限信息來配置動(dòng)態(tài)路由。
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`), // 動(dòng)態(tài)加載組件 meta: route.meta, permissions: route.permissions // 保存權(quán)限數(shù)據(jù) }; 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 根據(jù)權(quán)限動(dòng)態(tài)顯示按鈕
前端頁面上的操作按鈕(如增、刪、改、查)需要根據(jù)用戶對路由的權(quán)限來進(jìn)行顯示和隱藏。假設(shè)每個(gè)頁面都有這些按鈕,我們可以使用v-if指令來根據(jù)權(quán)限控制顯示與否。
<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>
在這個(gè)組件中,我們使用v-if指令根據(jù)權(quán)限來顯示對應(yīng)的按鈕。hasCreatePermission、hasUpdatePermission等計(jì)算屬性返回當(dāng)前用戶對該頁面的權(quán)限,setPermissions方法會(huì)在頁面加載時(shí)設(shè)置當(dāng)前用戶的權(quán)限。
3.3 在Vuex中存儲(chǔ)用戶權(quán)限
在Vuex中,我們可以存儲(chǔ)用戶的權(quán)限數(shù)據(jù),并在不同的組件中訪問。
// 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; } } });
四、總結(jié)
通過以上的設(shè)計(jì)和實(shí)現(xiàn),我們能夠在前端根據(jù)路由和權(quán)限動(dòng)態(tài)生成路由,并且為每個(gè)路由設(shè)置增、刪、改、查等操作的權(quán)限。后端負(fù)責(zé)根據(jù)用戶的角色返回對應(yīng)的權(quán)限信息,前端通過vue-router和vuex管理動(dòng)態(tài)路由和用戶權(quán)限。通過這種方式,系統(tǒng)可以靈活地根據(jù)角色和權(quán)限來展示不同的功能,并且有效地控制用戶對數(shù)據(jù)的操作權(quán)限。
這種設(shè)計(jì)方式非常適合復(fù)雜權(quán)限管理的系統(tǒng),能夠提供細(xì)粒度的權(quán)限控制,并且可以隨著業(yè)務(wù)需求的變化靈活調(diào)整。
到此這篇關(guān)于Vue中動(dòng)態(tài)權(quán)限到按鈕的完整實(shí)現(xiàn)方案詳解的文章就介紹到這了,更多相關(guān)Vue動(dòng)態(tài)權(quán)限內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue項(xiàng)目實(shí)現(xiàn)文件下載進(jìn)度條功能
大文件下載,花費(fèi)的時(shí)間比較長,沒有任何提示,用戶體驗(yàn)很差,需要優(yōu)化,提示文件在下載中,并且顯示進(jìn)度百分比,下面小編給大家?guī)砹薞ue項(xiàng)目實(shí)現(xiàn)文件下載進(jìn)度條功能,感興趣的朋友一起看看吧2024-03-03vue實(shí)現(xiàn)兩列水平時(shí)間軸的示例代碼
本文主要介紹了vue實(shí)現(xiàn)兩列水平時(shí)間軸的示例代碼,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11vue監(jiān)聽瀏覽器的后退和刷新事件,阻止默認(rèn)的事件方式
這篇文章主要介紹了vue監(jiān)聽瀏覽器的后退和刷新事件,阻止默認(rèn)的事件方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10100行代碼理解和分析vue2.0響應(yīng)式架構(gòu)
通過100行代碼幫助大家理解和分析vue2.0響應(yīng)式架構(gòu)的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03Vue父子組件數(shù)據(jù)雙向綁定(父傳子、子傳父)及ref、$refs、is、:is的使用與區(qū)別
這篇文章主要介紹了Vue父子組件數(shù)據(jù)雙向綁定(父傳子、子傳父)及ref、$refs、is、:is的使用與區(qū)別,需要的朋友可以參考下2022-12-12詳解Vue數(shù)據(jù)驅(qū)動(dòng)原理
這篇文章主要介紹了詳解Vue數(shù)據(jù)驅(qū)動(dòng)原理的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)vue框架的相關(guān)知識(shí),感興趣的朋友可以了解下2020-11-11vue-auto-focus: 控制自動(dòng)聚焦行為的 vue 指令方法
今天小編就為大家分享一篇vue-auto-focus: 控制自動(dòng)聚焦行為的 vue 指令方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-08-08