Skip to content

自定义图标

概述

系统支持两种图标使用方式:Element Plus 内置图标自定义 SVG 图标。通过自动化的图标注册机制,开发者只需将 SVG 文件放入指定目录,即可在全局范围内使用,无需手动导入和注册。

核心特性:

  • 🎨 自动注册 - SVG 文件放入 assets/icons/ 目录后自动注册为全局组件
  • 🔄 动态适配 - 支持主题色自动适配和自定义颜色
  • 📦 开箱即用 - 集成 Element Plus 全套图标库
  • 🚀 零配置 - 无需手动导入,全局可用

快速开始

添加自定义图标

以添加 run.svg 图标为例,操作步骤如下:

  1. 准备 SVG 文件(如 run.svg
  2. 将文件放入 ape-volo-web/src/assets/icons/ 目录
  3. 系统自动注册,文件名即为组件名
  4. 在任意 Vue 组件中直接使用

使用方式

方式 1:在 Element Plus 组件中使用

适用于 Button、Input 等支持 icon 属性的组件。

vue
<template>
  <!-- 自定义 SVG 图标 -->
  <el-button icon="run" type="primary"> 执行任务 </el-button>

  <!-- Element Plus 内置图标 -->
  <el-button icon="Search" type="success"> 搜索 </el-button>
</template>

方式 2:使用 <el-icon> 包裹

适用于需要独立展示图标或自定义图标样式的场景。

vue
<template>
  <!-- 自定义 SVG 图标 -->
  <div class="flex items-center gap-2">
    <el-icon><run /></el-icon>
    <span>执行任务</span>
  </div>

  <!-- Element Plus 内置图标 -->
  <div class="flex items-center gap-2">
    <el-icon><operation /></el-icon>
    <span>行为记录</span>
  </div>

  <!-- 自定义图标大小和颜色 -->
  <el-icon :size="20" color="#409eff">
    <run />
  </el-icon>
</template>

方式 3:直接使用组件

vue
<template>
  <!-- 作为独立组件使用 -->
  <run class="custom-icon" />

  <!-- 在列表中使用 -->
  <el-menu>
    <el-menu-item>
      <el-icon><run /></el-icon>
      <span>执行任务</span>
    </el-menu-item>
  </el-menu>
</template>

图标颜色适配

自动适配主题色

如果需要 SVG 图标自动适配主题色继承父元素颜色,需要在 SVG 文件中移除 fill 属性。

示例:

xml
<!-- ✅ 推荐:支持颜色自动适配 -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
  <path d="M12 2L2 7v10c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V7l-10-5z"/>
</svg>

<!-- ❌ 不推荐:固定颜色,无法适配主题 -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
  <path fill="#000000" d="M12 2L2 7v10c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V7l-10-5z"/>
</svg>

使用固定颜色

如果需要使用特定颜色的图标,保留 SVG 文件中的 fill 属性即可。

xml
<!-- 使用品牌色 -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
  <path fill="#409eff" d="M12 2L2 7v10c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V7l-10-5z"/>
</svg>

颜色控制优先级

  1. SVG 文件中的 fill 属性(最高优先级)
  2. CSS 样式中的 color 属性
  3. 父元素继承的颜色

技术实现原理

图标系统架构

系统在应用初始化阶段自动注册所有图标组件,包括 Element Plus 内置图标和自定义 SVG 图标。

配置文件: src/plugins/icons.js

javascript
import { h } from "vue";

import * as ElIconModules from "@element-plus/icons-vue";
import svgIcon from "@/components/svgIcon/svgIcon.vue";

/**
 * 创建SVG图标组件
 * @param {string} name - 图标名称
 * @returns {Object} Vue组件对象
 * @description 动态创建一个使用指定名称的SVG图标组件
 */
const createIconComponent = (name) => ({
  name: "SvgIcon",
  render() {
    return h(svgIcon, {
      name: name,
    });
  },
});

/**
 * 注册自定义SVG图标组件
 * @param {Object} app - Vue应用实例
 * @returns {Promise<void>} 无返回值的Promise
 * @description 扫描assets/icons目录下的SVG文件并注册为全局组件
 */
const registerIcons = async (app) => {
  // 使用Vite的glob导入功能获取所有SVG文件
  const iconModules = import.meta.glob("@/assets/icons/**/*.svg");
  const mergedIconModules = Object.assign({}, iconModules);

  // 遍历所有SVG文件路径
  for (const path in mergedIconModules) {
    // 从文件路径中提取图标名称
    const iconName = path
      .split("/")
      .pop()
      .replace(/\.svg$/, "");

    // 检查图标名称是否包含空格,如有则跳过并输出错误
    if (iconName.indexOf(" ") !== -1) {
      console.error(`icon ${iconName}.svg includes whitespace in ${path}`);
      continue;
    }

    // 创建图标组件并注册为全局组件
    const iconComponent = createIconComponent(iconName);
    app.component(iconName, iconComponent);
  }
};

/**
 * 设置图标系统
 * @param {Object} app - Vue应用实例
 * @returns {void}
 * @description 初始化图标系统,注册Element Plus图标和自定义SVG图标
 */
export const setupIcons = (app) => {
  // 注册所有Element Plus图标组件
  for (const iconName in ElIconModules) {
    app.component(iconName, ElIconModules[iconName]);
  }

  // 注册SVG图标组件
  app.component("SvgIcon", svgIcon);

  // 注册自定义SVG图标
  registerIcons(app);
};

注册流程说明

mermaid
graph LR
    A[应用启动] --> B[setupIcons]
    B --> C[注册 Element Plus 图标]
    B --> D[注册 SVG 图标组件]
    B --> E[扫描 assets/icons 目录]
    E --> F[提取文件名]
    F --> G[创建图标组件]
    G --> H[全局注册]
    H --> I[应用中可用]

关键步骤:

  1. 扫描目录 - 使用 Vite 的 import.meta.glob API 扫描 assets/icons/**/*.svg
  2. 提取名称 - 从文件路径提取文件名作为组件名(如 run.svgrun
  3. 创建组件 - 动态创建 Vue 组件包装 SVG 图标
  4. 全局注册 - 使用 app.component() 注册为全局组件
  5. 即时可用 - 在任意 Vue 组件中直接使用

常见问题

Q1: 图标不显示怎么办?

可能原因:

  1. 文件路径错误 - 确认 SVG 文件是否在 src/assets/icons/ 目录下
  2. 文件名包含空格 - 文件名不能包含空格,使用短横线或下划线(如 my-icon.svg
  3. 未重启开发服务器 - 添加新图标后需要重启 Vite 开发服务器
  4. 组件名冲突 - 避免使用与 Element Plus 图标同名的文件名

解决方案:

bash
# 1. 检查文件位置
ls src/assets/icons/

# 2. 重启开发服务器
npm run dev
# 或
yarn dev

Q2: 如何调整图标大小?

方法 1:使用 size 属性

vue
<el-icon :size="24"><run /></el-icon>

方法 2:使用 CSS

vue
<template>
  <el-icon class="large-icon"><run /></el-icon>
</template>

<style scoped>
.large-icon {
  width: 32px;
  height: 32px;
  font-size: 32px;
}
</style>

Q3: 如何批量管理图标?

推荐目录结构:

src/assets/icons/
├── common/          # 通用图标
│   ├── home.svg
│   ├── user.svg
│   └── setting.svg
├── business/        # 业务图标
│   ├── order.svg
│   ├── product.svg
│   └── customer.svg
└── status/          # 状态图标
    ├── success.svg
    ├── error.svg
    └── warning.svg

命名规范建议

  • 使用小写字母和短横线(如 my-icon.svg
  • 避免使用特殊字符和空格
  • 采用语义化命名(如 user-add.svgfile-download.svg
  • 保持命名简洁明了

Q4: 如何获取 Element Plus 图标列表?

访问 Element Plus 图标库 查看完整的图标列表和使用方法。

最佳实践

1. SVG 文件优化

使用 SVGO 等工具优化 SVG 文件,减小文件体积:

bash
# 安装 SVGO
npm install -g svgo

# 优化单个文件
svgo input.svg -o output.svg

# 批量优化
svgo -f ./icons -o ./icons-optimized

2. 图标尺寸规范

建议使用标准尺寸以保持视觉一致性:

场景推荐尺寸使用示例
小图标16px表格图标、状态指示
常规图标20-24px按钮、菜单
大图标32-48px空状态、引导页

3. 性能优化

  • ✅ 仅添加实际使用的图标,避免冗余
  • ✅ 定期清理未使用的 SVG 文件
  • ✅ 使用 SVGO 压缩 SVG 文件
  • ✅ 合理组织图标目录结构

参考资源

版权所有 © 2021-2026 ApeVolo-Team