跳转至

Element Plus 图标:为什么有的需要 import,有的不需要?

先看两种常见的图标用法

<!-- 写法一:作为 prop 传值 -->
<el-button :icon="ArrowLeft">返回</el-button>

<!-- 写法二:作为子组件在 el-icon 容器内 -->
<el-icon><Check /></el-icon>

核心区别ArrowLeft 作为对象传给 prop,Check 作为组件放进 el-icon 容器。


根本原因:两种用法,组件解析机制不同

写法一::icon="ArrowLeft" — prop 传组件对象

el-button 内部会直接使用 ArrowLeft 这个组件对象来渲染图标:

// el-button 内部伪代码
render() {
  return h(Button, { icon: ArrowLeft })  // 直接用这个对象
}

如果没 import,ArrowLeft 就是 undefined,按钮里什么都没有。

:material-import-icon: 必须 import,否则图标不显示。

写法二:<el-icon><Check /></el-icon> — 动态组件容器解析

el-icon 是一个动态组件容器,它会从 Vue 的全局组件注册表里查找 Check

// el-icon 内部伪代码
const iconName = 'Check'          // 从子组件名拿到
const component = resolveComponent(iconName)  // 从全局注册表查找
return h(component)

如果全局注册表里有 Check,就能找到并渲染。


你们项目为什么 Check 可以不 import?

看全局注册代码(src/components/SvgIcon/svgicon.js):

import * as components from '@element-plus/icons-vue'

export default {
  install: (app) => {
    for (const key in components) {
      const componentConfig = components[key]
      app.component(componentConfig.name, componentConfig)  // 全局注册
    }
  }
}

项目启动时把所有 Element Plus 图标都全局注册了,所以 Check 出现在 <el-icon> 里时,el-icon 能从全局注册表找到它,不需要手动 import


总结对比

用法 代码示例 是否需要 import 原因
prop 传图标 :icon="ArrowLeft" :fontawesome-solid-check:{ .green } 必须 import 需要组件对象本身
el-icon 容器 <el-icon><Check /></el-icon> :fontawesome-solid-xmark:{ .red } 不需要 el-icon 从全局注册表查找

建议:统一风格,全部 import

两种写法混着来容易出错,而且:

  • 全局注册会增加打包体积(虽然图标一般不大)
  • 不 import 就用,代码可读性差(阅读者得去查全局注册才知道从哪来的)
  • 容易漏掉导致 bug(哪天 el-icon 不从注册表找了,直接报错)

推荐统一写法,不管哪种用法都提前 import

<script setup>
import { Check, ArrowLeft } from "@element-plus/icons-vue";
</script>

<template>
  <!-- 两种写法都可以用,逻辑清晰 -->
  <el-button :icon="ArrowLeft">返回</el-button>
  <el-icon><Check /></el-icon>
</template>

最佳实践

代码一致性 > 代码量少。宁可多写一行 import,也让代码意图更明确。

如果项目图标用量大,建议把常用的图标抽取成一个公共文件集中管理:

// src/constants/icons.js
import { Check, ArrowLeft, Plus, Search } from "@element-plus/icons-vue";
export { Check, ArrowLeft, Plus, Search };

然后在需要的组件里:

import { Check, ArrowLeft } from "@/constants/icons.js";

评论