你是否曾经为在 Element Plus 项目中混用自定义图标而烦恼?明明 Element Plus 的图标用起来那么优雅,为什么自定义图标就显得格格不入?今天,我要分享一个激动人心的发现 —— 让你的自定义图标也能享受 Element Plus 同等的待遇!

💡 灵感时刻

在研究 Element Plus 的图标系统时,我注意到它们所有的图标都是用 currentColor 来控制颜色的。这让我思考:如果能把我们的自定义 SVG 图标也改造成这种方式,岂不是可以完美融入 Element Plus 的生态系统?

🎯 目标

  • 自定义图标与 Element Plus 图标体验完全一致

  • 支持颜色继承(使用 currentColor

  • 可自定义大小

  • 即插即用,零配置

✨ 完美方案:SVGIcon 组件

<template>
  <div v-html="svgContent" :style="{ width, height }"></div>
</template>

<script>
export default {
  name: 'SVGIcon',
  props: {
    src: {
      type: String,
      required: true,
    },
    width: {
      type: String,
      default: '1em', // 使用 em 单位,与 Element Plus 保持一致
    },
    height: {
      type: String,
      default: '1em',
    },
  },
  data() {
    return {
      svgContent: '',
    };
  },
  mounted() {
    this.loadSvg();
  },
  methods: {
    async loadSvg() {
      try {
        const response = await fetch(this.src);
        const svgText = await response.text();
        
        // 转换成 Element Plus 风格
        const updatedSvgText = svgText
          .replace(/fill="[^"]*"/g, 'fill="currentColor"')
          .replace(/(width|height)="[^"]*"/g, (match) => {
            if (match.startsWith('width')) {
              return `width="${this.width}"`;
            }
            return match.startsWith('height') ? `height="${this.height}"` : match;
          });

        this.svgContent = updatedSvgText;
      } catch (error) {
        console.error('SVG 加载失败:', error);
      }
    },
  },
};
</script>

<style scoped>
svg {
  display: inline-block;
  vertical-align: middle;
}
</style>

🚀 完美融入 Element Plus

<template>
  <el-button type="primary">
    <svg-icon src="/icons/custom-icon.svg" /> 
    自定义图标按钮
  </el-button>

  <!-- 与 Element Plus 图标混用 -->
  <el-button type="success">
    <el-icon><Edit /></el-icon>
    <svg-icon src="/icons/my-icon.svg" />
    完美融合
  </el-button>
</template>

<script setup>
import { Edit } from '@element-plus/icons-vue'
import SVGIcon from './components/SVGIcon.vue'
</script>

🌟 使用效果

  • 完全继承按钮文字颜色

  • 支持 hover 效果

  • 大小随文字自动调整

  • 对齐方式与官方图标一致

💪 进阶使用技巧

  1. 全局注册

// main.js
import SVGIcon from './components/SVGIcon.vue'
app.component('svg-icon', SVGIcon)

  1. 动态颜色

<el-button type="danger">
  <svg-icon src="/icons/alert.svg" />
  警告按钮
</el-button>

  1. 自定义大小

<svg-icon src="/icons/large-icon.svg" width="2em" height="2em" />

🎉 收获与感想

通过这个小组件,我们优雅地解决了自定义图标与 Element Plus 整合的问题。现在,无论是使用 Element Plus 自带图标还是自定义 SVG 图标,都能获得一致的开发体验和视觉效果。

这个方案不仅提高了开发效率,更重要的是保持了项目的整体一致性。每次看到自定义图标能够和 Element Plus 的图标和谐共处,都会有一种莫名的满足感!

🤔 后续优化方向

  • 添加图标预加载功能

  • 实现图标缓存机制

  • 支持精确的 TypeScript 类型提示

你也在为图标整合问题烦恼吗?快来试试这个方案吧!如果你有任何想法或建议,欢迎在评论区讨论交流~

记得点赞收藏,一起探索更多前端开发的美妙解决方案!🌟