菜单权限和路由权限

文章介绍了如何在Vue应用中实现菜单权限管理,包括定义全部菜单、根据用户权限动态加载菜单、处理路由权限配置以及解决刷新时路由丢失问题。还涉及角色label与value的转换和自定义hooks函数的使用。
摘要由CSDN通过智能技术生成
1.菜单权限
1.1定义全部菜单
//定义全部菜单
export const allMenus = [
    {
        id: "1",
        title: "aa首页",
        path: "/Admin/Home"
    },
    {
        id: "2",
        title: "bb管理",
        children: [
            {
                id: "2-1",
                title: "bb列表",
                path: "/Admin/Banners"
            }
        ]
    },
    {
        id: "3",
        title: "cc管理",
        children: [
            {
                id: "3-1",
                title: "cc列表",
                path: "/Admin/PersonList"
            }
        ]
    },
    {
        id: "4",
        title: "dd管理",
        children: [
            {
                id: "4-1",
                title: "dd1列表",
                path: "/Admin/GoodsList"
            },
            {
                id: "4-2",
                title: "dd2列表",
                path: "/Admin/SecondKill"
            },
            {
                id: "4-3",
                title: "dd3列表",
                path: "/Admin/RecommendList"
            },
            {
                id: "4-4",
                title: "dd4列表",
                path: "/Admin/FilterList"
            },
            {
                id: "4-5",
                title: "dd5详情",
                isShow:false,
                path: "/Admin/GoodsDetail"
            },
            {
                id: "4-6",
                title: "dd6列表",
                isShow:false,
                path: "/Admin/OrderList"
            }
        ]
    },
    {
        id: "5",
        title: "数据统计",
        children: [
            {
                id: "5-1",
                title: "ee1图",
                path: "/Admin/KLineChart"
            },
            {
                id: "5-2",
                title: "ee2图",
                path: "/Admin/BarChart"
            }
        ]
    },
    {
        id: "6",
        title: "ff列表",
        path: "/Admin/Citys"
        
    }
]
1.2根据当前用户的权限,得到对应的菜单
// 1、根据当前用户的权限,得到对应的菜单
import { allMenus } from "./data";

export function getCurrentMenus() {
    let checkedkeys: string[] = JSON.parse(sessionStorage.getItem("checkedkeys") as string);
    let adminname = sessionStorage.getItem("adminname");
    if (adminname === "admin") {
        return allMenus
    };
    let currMenus = [];
    // 1、循环外层
    allMenus.forEach(item => {
        if (checkedkeys?.includes(item.id)) {
            let objMenu = { ...item };
            if (item.children) {
                objMenu.children = [];
                // 2、循环第二层
                item.children.forEach(sonItem => {
                    if (checkedkeys.includes(sonItem.id)) {
                        objMenu.children.push({ ...sonItem });
                    }
                })
            }
            currMenus.push(objMenu);
        }
    })
    console.log("currMenus", currMenus);
    return currMenus;
}
1.3显示菜单
<template>
  <div>
    <el-menu active-text-color="#ffd04b" background-color="#545c64" :router="true" class="el-menu-vertical-demo" default-active="2"
      text-color="#fff" @open="handleOpen" @close="handleClose">
      <template v-for="item in currMenus" :key="item.id">
            <el-menu-item v-if="item.path" :index="item.path">
                <el-icon>
                    <FolderAdd />
                </el-icon>
                <span>{{ item.title }}</span>
            </el-menu-item>
            <el-sub-menu v-if="item.children" :index="item.id">
                <template #title>
                    <el-icon>
                        <FolderAdd />
                    </el-icon>
                    <span>{{ item.title }}</span>
                </template>
                <el-menu-item v-for="sonItem in item.children" :key="sonItem.id" :index="sonItem.path">
                    <el-icon>
                        <Document />
                    </el-icon>
                    <span>{{ sonItem.title }}</span>
                </el-menu-item>
            </el-sub-menu>
        </template>
    </el-menu>
  </div>
</template>

<script setup lang="ts">
import {
    Document,
   FolderAdd 
} from '@element-plus/icons-vue';

const handleOpen = (key: string, keyPath: string[]) => {
  console.log(key, keyPath)
}
const handleClose = (key: string, keyPath: string[]) => {
  console.log(key, keyPath)
}

import {getCurrentMenus} from "@/grant/index.ts"
const currMenus = getCurrentMenus();

</script>
2.路由权限
2.1定义权限相关路由配置
//定义权限相关路由配置
export const allroutes = [
    {
        id: "1",
        name: "Home",
        path: "",
        redirect: "/Admin/Home"
    },
    {
        id: "1",
        name: "Home",
        path: "Home",
        component: () => import("../views/Admin/Home/index.vue")
    },
    {
        id: "2-1",
        name: "Banners",
        path: "Banners",
        component: () => import("../views/Admin/Banners/index.vue")
    },
    {
        id: "3-1",
        name: "PersonList",
        path: "PersonList",
        component: () => import("../views/Admin/Person/PersonList.vue")
    },
    {
        id: "4-1",
        name: "GoodsList",
        path: "GoodsList",
        component: () => import("../views/Admin/Goods/GoodsList.vue")
    },
    {
        id: "4-2",
        name: "SecondKill",
        path: "SecondKill",
        component: () => import("../views/Admin/Goods/SecondKill.vue")
    },
    {
        id: "4-3",
        name: "RecommendList",
        path: "RecommendList",
        component: () => import("../views/Admin/Goods/RecommendList.vue")
    },
    {
        id: "4-4",
        name: "FilterList",
        path: "FilterList",
        component: () => import("../views/Admin/Goods/FilterList.vue")
    },
    {
        id: "4-5",
        name: "GoodsDetail",
        path: "GoodsDetail",
        component: () => import("../views/Admin/Goods/GoodsDetail.vue")
    },
    
    {
        id: "4-6",
        name: "OrderList",
        path: "OrderList",
        component: () => import("../views/Admin/Goods/OrderList.vue")
    },
    {
        id: "5-1",
        name: "KLineChart",
        path: "KLineChart",
        component: () => import("../views/Admin/Total/KLineChart.vue")
    },
    {
        id: "5-2",
        name: "BarChart",
        path: "BarChart",
        component: () => import("../views/Admin/Total/BarChart.vue")
    },
    {
        id: "6",
        name: "Citys",
        path: "Citys",
        component: () => import("../views/Admin/Citys/index.vue")
    }
]
2.2获取路由
//获取路由配置
import { allMenus, allroutes } from "./data";

function getAllCheckedKeys() {
    let arr = [];
    allMenus.forEach(item => {
        arr.push(item.id);
        if (item.children && Array.isArray(item.children)) {
            item.children.forEach(sonItem => {
                arr.push(sonItem.id);
            })
        }
    })
    return arr;
}

export function getCurrentRoutes($router) {
    console.log("getCurrentRoutes()");
    let adminname = sessionStorage.getItem("adminname");
    let checkedkeys: string[] = JSON.parse(sessionStorage.getItem("checkedkeys") as string);
    if (!checkedkeys) {
        return;
    }
    if (checkedkeys.length == 0) {
        // checkedkeys = getAllCheckedKeys();
        checkedkeys = ["1", '2', "2-1", "3-1", "4-1", "4-2", "4-3", "4-4", "5-1", "5-2", "6"]
    }
    // 1、删除所有的路由(权限相关的路由)
    allroutes.forEach(item => {
        $router.removeRoute(item.name);
    })
    console.log("删除路由后:$router.getRoutes()", $router.getRoutes());

    // 2、添加有权限的路由
    allroutes.forEach(item => {
        if (checkedkeys?.includes(item.id)) {
            $router.addRoute("Admin", { ...item });
        }
    })
    console.log("$router.getRoutes()", $router.getRoutes());
}
2.3登陆后进入布局layout页面
<template>
    <div class="common-layout">
        <el-container>
            <el-header>
                <h1>后台管理系统
                    <router-link to="/Login">
                        <span class="login">
                            <el-icon>
                                <UserFilled />
                            </el-icon>
                            退出登录
                        </span></router-link>
                    <span class="username">欢迎:{{ adminname }}</span>
                </h1>
            </el-header>
            <el-container class="container-main">
                <el-aside width="240px">
                    <Menu></Menu>
                </el-aside>
                <el-main>
                    <BreadCrumb></BreadCrumb>
                    <router-view></router-view>
                </el-main>
            </el-container>
        </el-container>
    </div>
</template>

<script  setup lang="ts">
import Menu from "./Menu.vue"
import BreadCrumb from "./BreadCrumb.vue";
import { useRouter } from 'vue-router';
import { getCurrentRoutes } from "@/grant";
import { UserFilled} from '@element-plus/icons-vue';
const $router = useRouter();
getCurrentRoutes($router);
const adminname = sessionStorage.getItem("adminname")
</script>
3.解决刷新时路由丢失问题(main.js)
import { getCurrentRoutes } from './grant';

// 解决刷新时,路由配置丢失的问题;
// 当刷新(刷新时,sessionStorage中是有权限数据的)时,需要重新添加权限路由
if(sessionStorage.getItem("checkedkeys")){
    // 刷新时
    getCurrentRoutes(router);
}
4.角色label与value值转换
export const roles = [
    {
        label:"超级管理员",
        value:0
    },
    {
        label:"管理员",
        value:1
    },
    {
        label:"其他",
        value:2
    }
]

//roleId和value转换
 <el-table-column label="角色" width="180">
   <template #default="scope">
     <div style="display: flex; align-items: center">                
       <span style="margin-left: 10px">{{ roles.filter(item => item.value == scope.row.role)[0]?.label }}</span>
     </div>
   </template>
</el-table-column>
5.自定义hooks函数
export function usePersonList() {
    const person: IPerson[] = reactive([]);
    // 获取操作人员列表
    const getPersonList = () => {
        getPersonListApi()
            .then((res: any) => {
                if (res.data.code === "200") {
                    person.length = 0;
                    person.push(...res.data.data);    
                }
            })
    }
    getPersonList();
    return {person,getPersonList};
}

//引入外部自定义hooks函数并使用
import { usePersonList } from "./PersonList"
const { person, getPersonList } = usePersonList();

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值