element-pluls中的动态el-menu中遇到的问题

问题一:点击菜单路由没效果

el-menu中添加   router

<el-menu
    active-text-color="#f9cc4b"
    text-color="white"
    background-color="#63779c"
    class="el-menu-vertical-demo"
    router
    :collapse="isCollapse"
  >
    <el-menu-item
      v-for="item in commonRouter"
      :key="item.name"
      :index="item.path"
    >
      <component  class="icons" :is="item.meta.icon" />
      <template #title>{{ item.meta.title }}</template>
    </el-menu-item>
  </el-menu>

import { commonRouter } from "@/router/index.js";

export const commonRouter = [{
    path: "/home",
    name: "home",
    meta: {
        title: "首页",
        icon: "ElementPlus"
    },
    component: () => import("@/views/index.vue")
}, {
    path: "/profile",
    name: "profile",
    meta: {
        title: "个人中心",
        icon: "UserFilled"
    },
    component: () => import("@/views/profile/index.vue")
}, {
    path: "/user",
    name: "user",
    meta: {
        title: "用户管理",
        icon: "Avatar"
    },
    component: () => import("@/views/user/index.vue")
}]

问题二:菜单根据当前路由保持高亮,刷新丢失

在el-menu 中增加    :default-active="active"

import { useRouter,useRoute } from "vue-router";
//方式一: const router
= useRouter(); const active=router.currentRoute.value.path;

//方式二:推荐
const route=useRoute();
const active=route.path;


下面是控制台输出router的结果

问题三:收缩菜单,右侧有明显的白线
.el-menu{//样式调整
  border:none !important;
}

问题四:菜单收缩卡顿

在el-menu中添加代码      :collapse-transition="false" 




问题五:动态图标
<component  class="icons" :is="item.meta.icon" />

下面是动态切换图标

<el-icon :size="25">
        <component class="icons" :is="isCollapse?'Expand':'Fold'" @click="handleChange"></component>
      </el-icon>




import {ref} from "vue"

let isCollapse=ref(false)

const handleChange = () => {
  isCollapse.value=!isCollapse.value;
};

 问题六:el-menu的宽度无法随着:collapse属性进行调整

方法一:   <el-aside style="width:auto"><el-menu>……</el-menu></el-aside>

方法二:   <el-aside style=" isCollapse?'width:180px':'width:64px' "><el-menu :collapse='isCollapse'>……</el-menu></el-aside>

定义isCollapse 绑定到el-menu中的collapse属性上

 

问题七: el-menu组件当菜单折叠后出现图标丢失的现象。问题出在el-icon元素在title模板内的使用。解决方法是将el-icon移出#title,但el-sub-menu的情况需保持el-icon在内,否则显示异常。调整后的代码使菜单项在展开和折叠状态下均能正确显示图标。

错误示范:

<el-menu-item
      v-if="hasChild(item) == 0"
      :index="resolvePath(item.path)"
      :key="resolvePath(item.path)"
    >
      <template #title>
        <el-icon>
          <component :is="item.meta?.icon" />
        </el-icon>
        <span>{{ item.meta?.title }}</span>
      </template>
    </el-menu-item>

正确使用: 把el-icon 从#title 中提取出来

   <el-menu-item
      v-if="hasChild(item) == 0"
      :index="resolvePath(item.path)"
      :key="resolvePath(item.path)"
    >
      <el-icon>
        <component :is="item.meta?.icon" />
      </el-icon>
      <template #title>
        <span>{{ item.meta?.title }}</span>
      </template>
    </el-menu-item>

 

 

动态路由,用户自己选的路由权限,有就展示,没有就隐藏

 

父组件

<template>
  <div>
    <el-row :gutter="20">
        <el-col :span="6">
        <el-menu
          active-text-color="#ffd04b"
          class="el-menu-vertical-demo"
          :default-active="activeRouter"
          :router="true"
        >
          <menu-item
           :menuList="routerList"
          ></menu-item>
        </el-menu>
      </el-col>
      <el-col :span="6"></el-col>
    </el-row>
  </div>
</template>

<script setup>
import { ref } from "vue";
import {  useUserInfoStore } from "@/store/index.js";
import { storeToRefs } from "pinia";
const useUserInfo = useUserInfoStore();
const { routerList } = storeToRefs(useUserInfo);
import MenuItem from "@/components/MenuItem.vue";
console.log("路由", routerList.value);
let realRouter = ref(["list1", "list2", "log1", "log2", "log3"]);//要展示的路由菜单
const activeRouter = ref("");

routerList.value.forEach((item) => {
  if (realRouter.value.indexOf(item.name) != -1) {
    item.isShow = true;
  }else{
   item.isShow=false;
  }
if (item.children) { item.children.forEach((im) => { if (realRouter.value.indexOf(im.name) != -1) { im.isShow = true; item.isShow = true; }else{ 
      im.isShow=false;
   }
}); } });
</script> <style scoped lang="scss"> </style>

pinia中定义的routerList数据

 let routerList = ref([{
        name: "home",
        path: "/",
        title: "首页",
        redireact: "/home",
        children: [{
            name: "list1",
            path: 'list1',
            title: "列表一"
        }, {
            name: "list2",
            path: 'list2',
            title: "列表二"
        }, {
            name: "list3",
            path: 'list3',
            title: "列表三"
        }]
    }, {
        name: "news",
        path: "/news",
        title: "新闻",
        children: [{
                name: "news1",
                path: "news1",
                title: "新闻一"
            },
            {
                name: "news2",
                path: "news2",
                title: "新闻二"
            },
            {
                name: "news3",
                path: "news3",
                title: "新闻三"
            },
        ]

    }, {
        name: "log",
        path: "/log",
        title: "日志",
        children: [{
                name: "log1",
                path: "log1",
                title: "日志一"
            },
            {
                name: "log2",
                path: "log2",
                title: "日志二"
            },
            {
                name: "log3",
                path: "log3",
                title: "日志三"
            },
        ]

    }])

子组件 MenuItem.vue

<template>
  <template v-for="item in props.menuList" :key="item.path">
   
        <!-- 没有子路由 item.meta.hidden为true是需要隐藏此路由 -->
    <template v-if="!item.children">
      <el-menu-item :index="item.path" v-if="item.isShow">
        <el-icon></el-icon>
        <template #title>
          <span>{{ item.title }}</span>
        </template>
      </el-menu-item>
    </template>
    <!-- 有子路由但是只有一个子路由 -->
    <template v-if="item.children && item.children.length == 1">
      <el-menu-item
        :index="item.children[0].path"
        v-if="!item.children[0].isShow"
      >
        <el-icon></el-icon>
        <template #title>
          <span>{{ item.children[0].title }}</span>
        </template>
      </el-menu-item>
    </template>


    <!-- 有子路由,且不止一个 -->
    <el-sub-menu
      :index="item.path"
      v-if="item.children && item.children.length > 1 &&item.isShow"
    >
      <template #title>
        <el-icon></el-icon>
        <span>{{ item.title }}</span>
      </template>
      <MenuItem :menuList="item.children"></MenuItem>
    </el-sub-menu>
  </template>
</template>

<script setup>
import { ref, reactive } from "vue";
const props = defineProps({
  menuList: {
    type: Array,
    default: [],
  },
});
</script>

<style scoped>
</style>

 

posted @ 2024-11-23 13:10  山吹同学  阅读(1046)  评论(0)    收藏  举报