| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- <template>
- <template v-for="subItem in menuList" :key="subItem.path">
- <el-sub-menu v-if="subItem.children?.length" :index="subItem.path">
- <template #title>
- <el-icon v-if="subItem.meta.icon">
- <component :is="subItem.meta.icon" />
- </el-icon>
- <span class="sle">{{ subItem.meta.title }}</span>
- </template>
- <SubMenu :menu-list="subItem.children" />
- </el-sub-menu>
- <el-menu-item v-else :index="subItem.path" @click="handleClickMenu(subItem)">
- <el-icon v-if="subItem.meta.icon">
- <component :is="subItem.meta.icon" />
- </el-icon>
- <template #title>
- <span class="sle">{{ subItem.meta.title }}</span>
- </template>
- </el-menu-item>
- </template>
- </template>
- <script setup lang="ts">
- import { useRouter } from "vue-router";
- import { ElMessage } from "element-plus";
- import { checkMenuClickPermission } from "@/utils/permission";
- defineProps<{ menuList: Menu.MenuOptions[] }>();
- const router = useRouter();
- const handleClickMenu = async (subItem: Menu.MenuOptions) => {
- if (subItem.meta.isLink) return window.open(subItem.meta.isLink, "_blank");
- if (!subItem.path) {
- ElMessage.warning("菜单路径不存在");
- return;
- }
- // 调用权限检查方法,判断是否可以点击(方法内部会显示相应的提示信息)
- const { canClick } = await checkMenuClickPermission(subItem.path);
- if (!canClick) {
- return;
- }
- // 允许访问,执行路由跳转
- try {
- await router.push(subItem.path);
- } catch (error: any) {
- handleRouteError(error);
- }
- };
- // 处理路由错误
- const handleRouteError = (error: any) => {
- // 如果是导航重复的错误,忽略它
- if (error?.name === "NavigationDuplicated") {
- return;
- }
- // 如果是路由不存在的错误
- if (error?.message?.includes("No match") || error?.message?.includes("not found")) {
- ElMessage.warning("该页面不存在或尚未配置");
- } else {
- console.error("路由跳转失败:", error);
- ElMessage.error("页面跳转失败,请稍后重试");
- }
- };
- </script>
- <style lang="scss">
- .el-sub-menu .el-sub-menu__title:hover {
- color: var(--el-menu-hover-text-color) !important;
- background-color: transparent !important;
- }
- .el-menu--collapse {
- .is-active {
- .el-sub-menu__title {
- color: #ffffff !important;
- background-color: var(--el-color-primary) !important;
- }
- }
- }
- .el-menu-item {
- &:hover {
- color: var(--el-menu-hover-text-color);
- }
- &.is-active {
- color: var(--el-menu-active-color) !important;
- background-color: var(--el-menu-active-bg-color) !important;
- &::before {
- position: absolute;
- top: 0;
- bottom: 0;
- width: 4px;
- content: "";
- background-color: var(--el-color-primary);
- }
- }
- }
- .vertical,
- .classic,
- .transverse {
- .el-menu-item {
- &.is-active {
- &::before {
- left: 0;
- }
- }
- }
- }
- .columns {
- .el-menu-item {
- &.is-active {
- &::before {
- right: 0;
- }
- }
- }
- }
- </style>
|