vue项目引入icon的问题

element-plus

官网给了两类方案

  1. 使用 @element-plus/icons-vue全局注册或手动 import ,写法是 <el-icon><Plus /></el-icon>(注意:如果想这么用组件,必须安装这个包,以及全局注册或手动引入。自动导入时不用安装这个包)
  2. 自动导入 :用 unplugin-icons + unplugin-auto-import 从 Iconify 自动导入任意图标集,并指向 element-plus-vite-starter 模板(注意,自动导入时是直接去图标大本营iconify找element的图标集去了,使用时写法不是官方<Plus />这种,而是<i-ep-plus />

自动导入注意事项

自动导入时的vite配置(同时组件也是自动引入)

  • 带//***注释的下面是本地svg文件自动引入
  • 具体icon格式:i-图标集名-图标名。图标组名用于vite.config.js里 Components/resolvers/IconsResolver/enabledCollections里配置图集名,以及pnpm add -D @iconify-json/图集名
js 复制代码
import path from 'path'
import { defineConfig } from 'vite'
import Vue from '@vitejs/plugin-vue'
import Icons from 'unplugin-icons/vite'
import IconsResolver from 'unplugin-icons/resolver'
import { FileSystemIconLoader } from 'unplugin-icons/loaders'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

const pathSrc = path.resolve(import.meta.dirname, 'src')

export default defineConfig({
  resolve: {
    alias: {
      '@': pathSrc,
    },
  },
  plugins: [
    Vue(),
    AutoImport({
      // Auto import functions from Vue, e.g. ref, reactive, toRef...
      // 自动导入 Vue 相关函数,如:ref, reactive, toRef 等
      imports: ['vue'],

      // Auto import functions from Element Plus, e.g. ElMessage, ElMessageBox... (with style)
      // 自动导入 Element Plus 相关函数,如:ElMessage, ElMessageBox... (带样式)
      resolvers: [
        ElementPlusResolver(),

        // Auto import icon components
        // 自动导入图标组件
        IconsResolver({
          prefix: 'Icon',
        }),
      ],

      dts: path.resolve(pathSrc, 'auto-imports.d.ts'),
    }),

    Components({
      resolvers: [
        // Auto register icon components
        // 自动注册图标组件
        IconsResolver({
          // 配置图标集合,需要提前npm安装依赖包后再配置进来
          enabledCollections: ['ep', 'material-symbols'],
          //***** 本地 SVG 图标集合(src/assets/icons)*******
          customCollections: ['local'],
        }),
        // Auto register Element Plus components
        // 自动导入 Element Plus 组件
        ElementPlusResolver(),
      ],

      dts: path.resolve(pathSrc, 'components.d.ts'),
    }),

    Icons({
      // *********** 本地 SVG 图标自动引入配置 **********
      customCollections: {
        // 本地 SVG 图标:src/assets/icons/*.svg,用法 <i-local-文件名 />
        // (如果svg图标本身就干净,这个第二个参数可以省略)
        local: FileSystemIconLoader('src/assets/icons', (svg) =>
          // 让图标颜色跟随 el-icon 的 color / CSS color
          svg.replace(/^<svg /, '<svg fill="currentColor" '),
        ),
      },
      //************************************************
    }),
  ],
})

配置中的prefix说明

这是 AutoImport(unplugin-auto-import)里 IconsResolver 的配置,作用与模板里的 <i-ep-xxx /> 不同------它负责在 script(JS 逻辑)中自动导入图标组件

具体效果

prefix: 'Icon' 规定:当代码中出现以 Icon 开头、后接「图集名 + 图标名」(PascalCase)的标识符时,自动导入对应的图标组件,无需手写 import:

js 复制代码
<script setup>
// 没有手写任何 import,下面这行也能直接用
// 等价于:import IconEpEdit from '~icons/ep/edit'
const editIcon = IconEpEdit
</script>

典型使用场景是图标需要作为 JS 值传递,而不是写在模板标签里:

js 复制代码
<script setup>
// ElMessageBox 的 icon 选项、动态组件 :is 等场景
const handleOpen = () => {
  ElMessageBox.confirm('确认删除?', { icon: IconEpWarning })
}


const dynamicIcon = shallowRef(IconEpEdit)
</script>


<template>
  <!-- el-button 的 icon 属性接收的是组件对象,绑定表达式在 script 作用域解析 -->
  <el-button :icon="IconEpEdit">编辑</el-button>
  <component :is="dynamicIcon" />
</template>
和另一处 IconsResolver 的分工
位置 前缀 管什么 例子
Components() 里(默认 i <i-ep-edit /> 模板标签的自动注册 <i-ep-edit />
AutoImport() 里(Iconvite里配置) IconEpEdit script 中标识符的自动导入 const x = IconEpEdit

两者前缀故意设得不同,避免同一个名字被两个插件重复解析。解析记录会写入 src/auto-imports.d.ts,IDE 也能获得类型提示。

简单说:模板里写标签用 <i-ep-edit />,JS 里当变量用 IconEpEdit,AutoImport/resolvers/ IconsResolver/prefix 是后者的开关。

引入本地svg文件

unplugin-icons提供支持,上面的文件里已有相关配置

关键前提:SVG 要"可染色、可缩放"。el-icon 通过 CSS 的 colorfont-size 控制子元素,所以 SVG 需要满足:

  • 颜色fill="currentColor"(或 stroke),不要用写死的颜色值,否则 color 属性无效
  • 尺寸width="1em" height="1em" 或不写宽高只留 viewBox,这样 :size="20" 才能生效

Iconify + unplugin-icons 是当前 Vue 3 主流方案

目前 Vue 3 社区更推荐的方式是基于 Iconify 生态 + SVG 按需加载,主要有两种用法:

方案 A:@iconify/vue(运行时加载)

html 复制代码
<template>
  <Icon icon="mdi:home" />
</template>
<script setup>
import { Icon } from '@iconify/vue'
</script>
  • 优点:使用简单,10 万+图标随时可用
  • 缺点:运行时通过 API 请求图标数据,有网络依赖

方案 B:unplugin-icons(构建时注入,antfu 出品,⭐4.3k)--- 更推荐

html 复制代码
<template>
  <!-- 直接当组件用,构建时自动按需打包,零运行时开销 -->
  <i-mdi-home />
  <i-carbon-settings />
</template>

配置(Vite):

js 复制代码
// vite.config.ts
import Icons from 'unplugin-icons/vite'
import Components from 'unplugin-vue-components/vite'
import IconsResolver from 'unplugin-icons/resolver'

export default defineConfig({
  plugins: [
    Components({
      resolvers: [
        IconsResolver({ prefix: 'i' })
      ]
    }),
    Icons({ compiler: 'vue3', autoInstall: true })
  ]
})

优势总结:

  • 按需编译时注入,零运行时网络请求
  • SSR/SSG 友好
  • 支持 Vue 3 / React / Svelte 等所有主流框架
  • 底层复用 Iconify 的 100+ 图标集(Material Design、Carbon、Tabler、Phosphor 等)
  • 可配合 UnoCSS 使用 <div class="i-mdi-home" /> 纯 CSS 方案
相关推荐
树上有只程序猿1 小时前
当低代码遇上AI,一个开发者的真实感悟
前端
郭邯1 小时前
从零手写一个 UA 解析工具:我用 AI 辅助开发,踩了这些坑
前端
Heo1 小时前
怎么保证缓存和数据库一致性?
前端·后端·面试
摇曳的精灵2 小时前
前端渲染优化
前端·前端渲染优化
WILLF2 小时前
前端视角:Python requests vs JS axios
前端·python
半个落月2 小时前
在浏览器里运行 DeepSeek-R1:React 对话界面与安全渲染(三)
前端·人工智能·react.js
Synmbrf2 小时前
micro-app 404 问题排查与修复
前端
西安栈上月明软件科技有限公司2 小时前
GEO 友好度检测器技术实现(已开源)
前端
汉堡大王95272 小时前
用 Trae Work 自动化任务,6 分钟生成一份前端生态周报
前端·javascript·人工智能