一、首先文件的层级关系:
1.svg文件夹,存放svg图标;
2.index.js文件:动态引入svg图标
注意:层级关系一定要正确,否则引入不了图标

二、index.js文件内容
javascript
// 1. 动态导入所有SVG文件
const svgModules = import.meta.glob('./svg/*.svg', {
as: 'raw', // 导入文件内容为字符串
eager: true // 立即加载
});
// 2. 创建SVG Sprite并添加到DOM
function createSvgSprite() {
const svgSprite = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
svgSprite.style.display = 'none';
svgSprite.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
// 遍历所有SVG模块
Object.entries(svgModules).forEach(([path, svgContent]) => {
// 提取图标名称
const iconName = path.replace(/^\.\/svg\/(.*)\.svg$/, '$1');
// 创建symbol元素
const symbol = document.createElementNS('http://www.w3.org/2000/svg', 'symbol');
symbol.id = `icon-${iconName}`;
// 提取SVG内容(移除svg标签本身)
const div = document.createElement('div');
div.innerHTML = svgContent;
const svgElement = div.querySelector('svg');
if (svgElement) {
// 复制 viewBox 属性
if (svgElement.hasAttribute('viewBox')) {
symbol.setAttribute('viewBox', svgElement.getAttribute('viewBox'));
}
// 复制所有子元素
while (svgElement.firstChild) {
symbol.appendChild(svgElement.firstChild);
}
// 添加到sprite
svgSprite.appendChild(symbol);
}
});
// 添加到页面
document.body.appendChild(svgSprite);
}
// 执行创建
createSvgSprite();
// 导出图标名称列表
export const iconNames = Object.keys(svgModules).map(path =>
path.replace(/^\.\/svg\/(.*)\.svg$/, '$1')
);
三、在components文件夹下创建index.vue文件
javascript
<template>
<svg
class="icon"
:class="[$attrs.class, 'icon-' + name]"
:style="iconStyle"
aria-hidden="true"
>
<use :href="`#icon-${name}`"></use>
</svg>
</template>
<script setup>
import { computed, defineProps, inject } from "vue";
// 接收外部属性
const props = defineProps({
name: {
type: String,
required: true,
validator: (value) => {
// 可选:验证图标名称是否存在
return true;
},
},
color: {
type: String,
default: undefined,
},
size: {
type: [Number, String],
default: undefined,
},
});
// 计算最终样式
const iconStyle = computed(() => ({
width: props.size || "18px",
height: props.size || "18px",
color: props.color || "#fff",
}));
</script>
<script>
export default {
name: "SvgIcon",
inheritAttrs: false, // 阻止默认继承,避免属性重复应用
};
</script>
<style scoped>
.icon {
display: inline-block;
vertical-align: middle;
overflow: hidden;
fill: currentColor; /* 关键:使用currentColor继承文本颜色 */
}
/* 解决样式穿透问题 */
:deep(svg) {
width: 100%;
height: 100%;
}
</style>
四、plugins文件夹下创建svg_icon.js文件
javascript
import { createApp } from 'vue';
import Icon from '@/components/SvgIcon';
import '@/assets/icon'; // 导入SVG Sprite
export default {
install(app, options = {}) {
// 提供全局配置
app.provide('iconConfig', {
color: options.color || 'currentColor',
size: options.size || '24px'
});
// 注册全局组件
app.component('Icon', Icon);
}
};
// 批量导出图标名称(可选)
export * from '@/assets/icon';
五、在main.js文件中引入
javascript
import SvgIconPlugin from '@/plugins/svg_icon'
// 安装icon插件,可配置全局默认值
app.use(SvgIconPlugin, {
color: "#fff",
size: "18px"
})
六、使用
name:将文件下载下来以后的命名
javascript
<SvgIcon
name="uls_icon"
size="18"
color="#00ffff"
/>