一、问题描述

平时在使用 el-menu 编写菜单组件时,一般都会为每一个菜单项 item 配置一个图标和名称,如下图所示。通常我们会使用 v-for 循环动态渲染 el-menu-item。那么在 Vue + Vite + Element Plus项目中配置自动引入 Element Plus 的图标后该如何编写代码呢?
在这里插入图片描述
这时我们会想到通过使用 Vue 中的 component 组件来实现,代码如下:

<template>
  <div class="main-container">
    <el-menu default-active="图标1" class="category-menu">
      <el-menu-item :index="menuIcon.name" v-for="menuIcon in menuIconList" :key="menuIcon.name">
        <el-icon>
          <component :is="menuIcon.icon"></component>
        </el-icon>
        <span>{{ menuIcon.name }}</span>
      </el-menu-item>
    </el-menu>
  </div>
</template>

<script setup>
const menuIconList = reactive([
  {
    name: '图标1',
    icon: "Menu"
  },
  {
    name: '图标2',
    icon: "Comment"
  },
  {
    name: '图标3',
    icon: "QuestionFilled"
  }
])
</script>

运行之后发现图标并没有显示出来,这是为什么呢?

二、引发原因

【原因1】:在 Vue3 中,component 动态组件的 is 属性必须绑定的是组件实例,而不是组件名字,所以需要去掉双引号。
【原因2】:在 vite.config.js 中配置了图标前缀 Icon 和图标库集合 ep,所以在写图标名称是需要加上前缀,并且使用驼峰命名。(vite.config.js 的详细配置可以参考这篇文章

// vite.config.js
export default defineConfig({
  plugins: [
    vue(),
    AutoImport({
      resolvers: [
        // 自动导入 Element Plus 相关函数,如:ElMessage, ElMessageBox... (带样式)
        ElementPlusResolver(),
        // 自动导入图标组件
        IconsResolver({
          prefix: 'Icon'
        })
      ]
    }),
    Components({
      resolvers: [
        // 自动导入 Element Plus 组件
        ElementPlusResolver(),
        // 自动注册图标组件
        IconsResolver({
          enabledCollections: ['ep']
        })
      ]
    }),
    Icons({
      autoInstall: true
    })
  ]
})

三、解决方法

修改图标名称,完整代码如下所示:

<template>
  <div class="main-container">
    <el-menu default-active="图标1" class="category-menu">
      <el-menu-item :index="menuIcon.name" v-for="menuIcon in menuIconList" :key="menuIcon.name">
        <el-icon>
          <component :is="menuIcon.icon"></component>
        </el-icon>
        <span>{{ menuIcon.name }}</span>
      </el-menu-item>
    </el-menu>
  </div>
</template>

<script setup>
const menuIconList = reactive([
  {
    name: '图标1',
    icon: IconEpMenu
  },
  {
    name: '图标2',
    icon: IconEpComment
  },
  {
    name: '图标3',
    icon: IconEpQuestionFilled
  }
])
</script>

四、附录

  1. 动态图标组件
Logo

前往低代码交流专区

更多推荐