element-plus
官网给了两类方案:
- 使用
@element-plus/icons-vue:全局注册或手动 import ,写法是<el-icon><Plus /></el-icon>(注意:如果想这么用组件,必须安装这个包,以及全局注册或手动引入。自动导入时不用安装这个包) - 自动导入 :用
unplugin-icons+unplugin-auto-import从 Iconify 自动导入任意图标集,并指向element-plus-vite-starter模板(注意,自动导入时是直接去图标大本营iconify找element的图标集去了,使用时写法不是官方<Plus />这种,而是<i-ep-plus />)
自动导入注意事项
- 要安装iconify里对应的图集 icon-sets.iconify.design/
- element-plus
pnpm add -D @iconify-json/epicon-sets.iconify.design/ep/?keyword... - material-symbols
pnpm add -D @iconify-json/material-symbols(需要什么图集就要先装包,最后在vite.config.js里配置进去)
- element-plus
- vite的
自动导入时的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 的color和font-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 方案