UseSvgIcon - Svg图标
组件介绍
UseSvgIcon 是基于 Vue3 + TypeScript 封装的 SVG 图标组件,配合 vite-plugin-svg-icons 实现本地 SVG 图标按需加载,专注于标准化项目内 SVG 图标的使用方式,内置尺寸自适应、明暗模式颜色自动切换、交互状态控制能力,完整支持自定义大小、颜色、边距、点击交互,无需重复编写SVG use标签,大幅降低项目内图标使用的重复代码,统一图标渲染规范。
核心能力
- 零配置的SVG图标渲染
内置SymbolId自动拼接逻辑,自动生成
#icon-{name}格式的symbol地址,与vite-plugin-svg-icons默认symbolId配置完全对齐,仅需传入图标名称(对应SVG文件名)即可完成图标渲染,默认添加aria-hidden="true"无障碍属性,无需手动编写SVG结构和处理资源路径,开箱即用。
- 灵活的尺寸自适应能力
size属性同时支持数字(默认单位为px)和带单位的字符串(如20px、0.2rem、1.5em)两种传参方式,内置单位合法性校验,默认尺寸为28px,自动同步图标宽高保证原始比例不变,无需分别设置width和height,适配不同场景下的图标尺寸需求。
- 原生支持明暗双模式颜色切换
color属性支持单颜色字符串和长度为2的颜色数组两种传参模式:传字符串时为固定图标颜色;传数组时第一项为默认模式颜色,第二项为暗黑模式下的颜色,组件自动识别项目
.dark暗黑模式根类名切换颜色,无需额外编写暗黑模式样式覆盖,自动处理颜色填充逻辑,无缝适配明暗主题切换。
- 开箱即用的交互状态控制
内置clickable开关属性,开启后自动将鼠标指针设置为pointer手型,无需额外编写cursor样式;支持传入自定义hoverClass类名,可灵活扩展hover交互效果(如颜色变化、缩放、透明度变化),无需额外包裹容器即可实现图标交互效果。
- 便捷的外边距控制
原生支持margin属性,完全兼容CSS margin规则,支持传单边值(如"8px")、多边值(如"0 4px")、不同单位边距,直接在组件上设置图标与周围元素的间距,无需额外包裹容器或编写自定义样式调整图标位置。
- 严格的开发阶段类型校验
所有Props内置完整的类型校验和合法性校验:size属性自动校验单位合法性,非法单位传参在开发阶段抛出异常;color属性为数组时自动校验长度(不能为空数组、最多支持2项),非法传参提前抛出错误;name为必传属性,从开发阶段避免非法传参导致的图标渲染异常。
- 自然的上下文样式继承
组件默认fill为currentColor,未传入color属性时自动继承父元素的文字颜色,与周围文字排版自然融合,无需额外设置颜色即可匹配文本主题;使用scoped样式隔离,无全局样式污染,保证组件在不同布局场景下的样式一致性。
- 轻量高性能无额外依赖
组件仅依赖Vue3响应式能力和项目内通用工具函数,无任何第三方图标库或运行时依赖,基于本地SVG图标资源按需渲染,体积轻量,渲染性能高,不会引入全量图标包导致的体积冗余,适配中后台系统的性能优化需求。
使用
Props
import type { PropType } from 'vue'
import { isArray, isNumber } from '@wyfex/iutils'
import { parseUnit, isValidUnit } from '@/utils'
/**
* 组件props
*/
export default {
/**
* 图标名称 必传
*/
name: {
type: String,
required: true
},
/**
* 图标大小 默认类型为数字(单位为px);可传带单位的字符串,如:20px、0.2rem
*/
size: {
type: [Number, String],
default: 28,
validator(val: any) {
if (isNumber(val)) return val
return isValidUnit(parseUnit(val)) && val
}
},
/**
* 图标颜色 可传String或Array
* 若传Array,只能传两项 第一项为默认图标颜色 第二项为暗黑模式下图标颜色
*/
color: {
type: [String, Array] as PropType<string | Record<string, any>[]>,
validator(val: any) {
if (!isArray(val)) return val
if (!val.length) throw new Error(`color类型为Array时length不能为0`)
if (val.length > 2) throw new Error(`color类型为Array时length最大为2`)
return val
}
},
/**
* 图标的margin外边距 同css的margin规则
*/
margin: {
type: String
},
/**
* 是否可点击
*/
clickable: {
type: Boolean,
default: false
},
/**
* hover类名
*/
hoverClass: {
type: String
}
}注意事项
1、使用该组件需在vite.config.ts中进行如下配置:
// pnpm i -D vite-plugin-svg-icons
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
export default defineConfig({
plugins: [
createSvgIconsPlugin({
iconDirs: [resolve(process.cwd(), 'src/assets/svgs')],
symbolId: 'icon-[name]'
})
]
})2、然后在plugins/modules/WyfeXIVue.ts或main.ts中引入:
import 'virtual:svg-icons-register'