vue3 element-plus动态菜单及动态图标

1. 安装element-plus及图标库

# NPM
$ npm install @element-plus/icons-vue
# Yarn
$ yarn add @element-plus/icons-vue
# pnpm
$ pnpm install @element-plus/icons-vue


# NPM
$ npm install element-plus --save

# Yarn
$ yarn add element-plus

# pnpm
$ pnpm install element-plus

2.全局引入

引入element-plus

//引入element-plus
import ElementPlus from 'element-plus'
const app = createApp(App)
app.use(ElementPlus)

注册图标组件

// main.ts

// 如果您正在使用CDN引入,请删除下面一行。
import * as ElementPlusIconsVue from '@element-plus/icons-vue'

const app = createApp(App)
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
  app.component(key, component)
}

3. 动态菜单代码

动态引入图标代码

<el-icon>
   <component  v-if="item.meta" :is="item.meta.icon"></component>
</el-icon>

完整代码

<template>
  <el-menu
    active-text-color="#ffd04b"
    background-color="#545c64"
    text-color="#fff"
    default-active="2"
    router
    class="el-menu-vertical-demo"
    :collapse="props.isCollapse"
    :ellipsis="false"
    @open="handleOpen"
    @close="handleClose"
  >
    <!-- <el-sub-menu index="/home">
      <template #title>
        <el-icon><location /></el-icon>
        <span>常用功能</span>
      </template>
        <el-menu-item index="/throttle">节流</el-menu-item>
        <el-menu-item index="/debounce">防抖</el-menu-item>
    </el-sub-menu>
    <el-menu-item index="2">
      <el-icon><icon-menu /></el-icon>
      <template #title>Navigator Two</template>
    </el-menu-item>
    <el-menu-item index="3" disabled>
      <el-icon><document /></el-icon>
      <template #title>Navigator Three</template>
    </el-menu-item>
    <el-menu-item index="4">
      <el-icon><setting /></el-icon>
      <template #title>Navigator Four</template>
    </el-menu-item> -->
    <template v-for="item in menuRoutes" :key="item.id">
        <el-sub-menu  v-if="item.children && item.children.length > 0" :index="item.path">
          <template #title>
            <el-icon>
              <component  v-if="item.meta" :is="item.meta.icon"></component>
            </el-icon>
              <!-- <el-icon><location /></el-icon> -->
              <span v-if="item.meta">{
   
   {item.meta.title}}</span>
          </template>
          <!-- 二级菜单 -->
            <el-menu-item v-for="item2 in item.children" :key="item2.id" :index="item2.path" :style="item2.children?'display: none': null">
              {
   
   {item2.children? null : item2.meta.title}}
            </el-menu-item>
          <!-- 三级菜单 -->
            <el-sub-menu v-for="item2 in item.children.filter(x => x.children && x.children.length > 0)" :key="item2.id" class="child-sub-menu" :index="item2.path">
              <template #title>
                <!-- <component  v-if="item.meta" :is="item.meta.icon" style="width: 20px; height: 20px"></component> -->
                <!-- <el-icon><location /></el-icon> -->
                  <span v-if="item2.meta">{
   
   {item2.meta.title}}</span>
              </template>
              <el-menu-item v-for="item3 in item2.children" :key="item3.id" :index="item3.path">{
   
   {item3.meta.title}}</el-menu-item>
            </el-sub-menu>
          <!-- </template> -->
        </el-sub-menu>
        <el-menu-item v-else :index="item.path">{
   
   {item.meta.title}}</el-menu-item>
    </template>
  </el-menu>
</template>

<script lang="ts" setup>
import { ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { menuRoutes } from '@/router/index'
const router = useRouter()
const props = defineProps({
  isCollapse: {
		type: Boolean,
		default: false,
  }
})
const emits = defineEmits(['menuChange'])
const handleOpen = (key: string, keyPath: string[]) => {
  console.log(key, keyPath)
}
const handleClose = (key: string, keyPath: string[]) => {
  console.log(key, keyPath)
}
onMounted(() => {
    console.log(router.options.routes)
})
</script>

<style>
.el-menu-vertical-demo:not(.el-menu--collapse) {
  width: 200px;
  min-height: 400px;
}
</style>
<style lang="stylus" scoped>
.el-menu
  height: 100vh
  border-right: none
:deep(.el-sub-menu__title)
  height: 50px !important
</style>

路由如下

export const menuRoutes: Array<RouteRecordRaw> = [
    {
        path: '/adminHome',
        name: 'adminHome',
        meta: {
            title: '常用功能',
            icon: 'location'
        },
        component: () => import('@/views/adminHome.vue'),
        children: [
            {
                path: '/debounce',
                name: 'debounce',
                meta: {
                    title: '防抖',
                    icon: 'location'
                },
                component: () => import('@/views/adminsystem/debounce/index.vue')
            },
            {
                path: '/throttle',
                name: 'throttle',
                meta: {
                    title: '节流',
                    icon: 'location'
                },
                component: () => import('@/views/adminsystem/throttle/index.vue')
            }
        ]
    }
]

猜你喜欢

转载自blog.csdn.net/KK_vicent/article/details/129274671