rbac 权限

用户\权限\菜单关系

image

前端逻辑与实现

vuex内

import {createStore} from 'vuex'

export default createStore({
    state: {
        token: localStorage.getItem('username') || '',
        routers: localStorage.getItem('routers') || '',
        menus: localStorage.getItem('menus') || '',
        permissions: localStorage.getItem('permissions') || '',
    },
    getters: {
        //将值转成对象
        routers: state => JSON.parse(state.routers),
        menus: state => JSON.parse(state.menus),
        permissions: state => JSON.parse(state.permissions),
        token: state => state.token,
    },
    mutations: {
        login(state, data) {
            state.token = data.token
            //将值转成字符串
            state.routers = JSON.stringify(data.routers)
            state.menus = JSON.stringify(data.menus)
            state.permissions = JSON.stringify(data.permissions)
            localStorage.setItem('username', state.token)
            localStorage.setItem('routers', state.routers)
            localStorage.setItem('menus', state.menus)
            localStorage.setItem('permissions', state.permissions)
        }
    },
    actions: {},
    modules: {}
})

登陆

const onFinish = values => {
    let data = {
        token: values.password,
        //拥有路由的权限
        routers: ["admin", "menu1", "user",],
        // 拥有菜单的权限
        menus: [
            {
                id:1,
                title: "权限管理",
                icon: "AppstoreOutlined",
                children: [
                    {
                        title: "菜单",
                        name: "menu1",
                    },
                    {
                        title: "角色",
                        name: "menu1",
                    },
                    {
                        title: "用户",
                        name: "menu1",
                    },
                ]
            }
        ],
        // 拥有接口的权限
        permissions: {
            "user":["POST","PUT","DELETE"],
            "order":["GET","PUT","DELETE"],
        },
    }
    store.commit('login', data)
    router.replace({name: data.routers[0]})
};

菜单匹配

<template>
            <a-menu theme="dark" mode="inline">
                <a-sub-menu :key="menu.id" v-for="menu in menuList">
                    <template #title>
            <span>
                <component :is="menu.icon" />
              <span>{{ menu.title }}</span>
            </span>
                    </template>
                    <a-menu-item v-for="child in menu.children" :key="child.title">
                        <router-link :to="{name:child.name}">{{ child.title }}</router-link>
                    </a-menu-item>
                </a-sub-menu>
            </a-menu>
</template>
<script setup>
import {computed, defineComponent, ref} from 'vue';
import {useStore} from 'vuex';
const store = useStore();
const menuList = computed(() => store.getters.menus);
</script>

前端路由权限匹配(导航守卫)

router.beforeEach((to, from, next) => {
    // 路由守卫
    if (store.getters.routers.indexOf(to.name) !== -1) {
        next()
    }
    if (to.name === 'login') {
        next()
    }
    if (!store.getters.routers) {
        next({name: 'login'})
    }
    next({name: store.getters.routers[0]})
})

后端接口权限判断

<a v-permission="['user','GET']">增</a>

import store from "@/store";
export default {
    // el 是指令绑定的元素,bindings是入参
    mounted(el, bindings) {
        let [def, method] = bindings.value;
        let userPermission = store.getters.permissions;
        if(!userPermission[def]){
            el.parentNode && el.parentNode.removeChild(el);
        }
        // 无权限,则不加载
        if (userPermission[def].indexOf(method) === -1) {
            el.parentNode && el.parentNode.removeChild(el);
        }
    }
}
posted @ 2023-04-09 18:32  Sherwin_szw  阅读(16)  评论(0编辑  收藏  举报