在vue3项目中如何优雅的管理svg图标

在 Vue3 项目中,将 SVG 图标集中管理并方便地在各个组件中使用,是一个非常常见的需求。结合“可变色”和“公共管理”这两个核心点,以下是几种最佳实践方案:

方案一:SVG 组件化 + 自动导入

这是目前最流行、最灵活、最易维护的方式。将每个 SVG 文件转换为一个独立的 Vue 组件,并通过工具自动注册。

目录结构

src/
├── components/
│ └── SvgIcon.vue # 通用 SVG 图标组件
├── assets/
│ └── icons/ # 所有 SVG 文件集中存放
│ ├── user.svg
│ ├── home.svg
│ ├── setting.svg
│ └── ...
└── plugins/
└── svgIcon.js # SVG 组件自动导入脚本

创建通用 SVG 组件 SvgIcon.vue

<!-- components/SvgIcon.vue -->
<template>
<svg
:class="['svg-icon', className]"
:style="{ width: size, height: size, color: color }"
aria-hidden="true"
<use :href="symbolId" :fill="color" />
</svg>
</template>

<script setup>
import { computed } from 'vue'

const props = defineProps({
// 图标名称,如 'user'
name: {
type: String,
required: true
},
// 图标大小
size: {
type: String,
default: '1em'
},
// 图标颜色(支持 CSS 颜色值)
color: {
type: String,
default: 'currentColor'
},
// 自定义 class
className: {
type: String,
default: ''
}
})

// 生成 symbol 的 ID,格式为 #icon-name
const symbolId = computed(() => #icon-${props.name})
</script>

<style scoped>
.svg-icon {
display: inline-block;
vertical-align: -0.15em;
fill: currentColor; / 关键:让 fill 继承 color /
overflow: hidden;
}
</style>

自动导入 SVG 文件并注册为 symbol

// plugins/svgIcon.js
import { createApp } from 'vue'

// 使用 import.meta.glob 动态导入 assets/icons/ 下的所有 .svg 文件
const svgModules = import.meta.glob('@/assets/icons/*.svg', { as: 'raw', eager: false })

// 在应用启动时执行
export function setupSvg(app) {
const div = document.createElement('div')
div.style.display = 'none'
let svgStr = '<svg xmlns="http://www.w3.org/2000/svg">'

// 遍历所有 SVG 文件
Object.keys(svgModules).forEach(async (path) => {
const response = await svgModules[path]()
// 提取文件名作为 icon name
const name = path.match(/\/([^/]+)\.svg$/)[1]
// 将 SVG 内容包装成 <symbol>
const symbol = response
.replace('<svg', <symbol id="icon-${name}")
.replace('</svg>', '</symbol>')
svgStr += symbol
})

svgStr += '</svg>'
div.innerHTML = svgStr
document.body.insertBefore(div, document.body.firstChild)
}

在 main.js 中注册

// main.js
import { createApp } from 'vue'
import App from './App.vue'
import { setupSvg } from './plugins/svgIcon'

const app = createApp(App)

// 注册 SVG 图标
setupSvg(app)

app.mount('#app')
5. 在任意组件中使用

vue
<template>
<div>
<!-- 使用 -->
<SvgIcon name="user" size="24px" color="red" />
<SvgIcon name="home" color="blue" />
<SvgIcon name="setting" style="color: green;" />
</div>
</template>

<script setup>
// 只需引入一次组件即可
import SvgIcon from '@/components/SvgIcon.vue'
</script>

优点:

  1. 集中管理所有 SVG 文件
  2. 支持动态变色(通过 color 属性)
  3. 支持按需加载(import.meta.glob)
  4. 使用简单,像使用普通组件一样 构建时自动处理,无需手动维护

方案二:使用第三方库(如 vite-plugin-svg-icons)

如果你使用 Vite,可以使用现成的插件,更加省事。

安装

npm install vite-plugin-svg-icons -D

配置 vite.config.js

import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
import path from 'path'

export default {
plugins: [
createSvgIconsPlugin({
// 指定 SVG 文件夹
iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')],
// 指定 symbolId 格式
symbolId: 'icon-[name]'
})
]
}

在 main.js 中引入生成的脚本

// main.js
import 'virtual:svg-icons-register' // 插件会生成这个虚拟模块

使用方式同方案一的 SvgIcon.vue 组件

只需创建一个通用的 SvgIcon.vue 组件,然后在项目中使用即可。

不推荐的方式

  1. <img src="xxx.svg">:无法通过 CSS 改变颜色。
  2. CSS background-image:同样无法控制内部颜色,且不利于响应式。
  3. 手动维护所有 SVG 内容:维护成本高,不推荐。

总结

  • 组件化 + 自动导入 强烈推荐 纯手动实现,灵活可控
  • vite-plugin-svg-icons 推荐 使用 Vite 插件,更简单
  • 内联 SVG 代码 一般 适合图标少的项目
  • img或 background 不推荐 无法变色

选择 方案一 或 方案二,将 SVG 集中管理,通过 SvgIcon 组件统一调用,既能实现变色,又能方便维护。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sherry Tian

打赏1元鼓励作者

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值