Vue文件
src/components/svgIcon/SvgIcon.vue
<template>
<svg :class="svgClass" v-bind="$attrs" :style="{width,height,color}">
<use :href="svgName"></use>
</svg>
</template>
<script setup>
import {computed} from "vue";
const props = defineProps({
//图标名称 如 home
iconName: {
type: String,
default: ""
},
//对不同区域的 icon 样式调整,如字体大小
className: {
type: String,
default: ""
},
width: {
type: Number,
default: 16
},
height: {
type: Number,
default: 16
},
color: {
type: String,
default: "#888"
}
})
const svgName=computed(()=>`#icon-${props.iconName}`);
const svgClass=computed(()=>{
if(props.name){
return `svg-icon icon-${props.iconName}`
}
return `svg-icon`
})
</script>
<style>
.svg-icon {
width: 16px;
height: 16px;
vertical-align: -0.15em;
fill: currentColor; /*此属性为更改svg颜色属性设置*/
stroke: currentColor;
overflow: hidden;
margin-right: 8px;
}
</style>
在main.js中引入SvgIcon组件
import SvgIcon from '@/components/svgIcon/SvgIcon.vue' // 引入自定义组件
createApp(App)
.use(store)
.use(router)
.component('svg-icon', SvgIcon) // 注册到全局
.mount('#app')
写个插件
创建文件svgBuilder.js
文件结构如下,svg中是svg的图片文件 就不打开了

插件代码
网上的代码
import { readFileSync, readdirSync } from "fs";
let idPerfix = "";
const svgTitle = /<svg([^>+].*?)>/;
const clearHeightWidth = /(width|height)="([^>+].*?)"/g;
const hasViewBox = /(viewBox="[^>+].*?")/g;
const clearReturn = /(\r)|(\n)/g;
function findSvgFile(dir) {
const svgRes = [];
const dirents = readdirSync(dir, {
withFileTypes: true,
});
for (const dirent of dirents) {
if (dirent.isDirectory()) {
svgRes.push(...findSvgFile(dir + dirent.name + "/"));
} else {
const svg = readFileSync(dir + dirent.name)
.toString()
.replace(clearReturn, "")
.replace(svgTitle, ($1, $2) => {
let width = 0;
let height = 0;
let content = $2.replace(clearHeightWidth, (s1, s2, s3) => {
if (s2 === "width") {
width = s3;
} else if (s2 === "height") {
height = s3;
}
return "";
});
if (!hasViewBox.test($2)) {
content += `viewBox="0 0 ${width} ${height}"`;
}
return `<symbol id="${idPerfix}-${dirent.name.replace(
".svg",
""
)}" ${content}>`;
})
.replace("</svg>", "</symbol>");
svgRes.push(svg);
}
}
return svgRes;
}
export const svgBuilder = (path, perfix = "icon") => {
if (path === "") return;
idPerfix = perfix;
const res = findSvgFile(path);
return {
name: "svg-transform",
transformIndexHtml(html) {
return html.replace(
"<body>",
`
<body>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position: absolute; width: 0; height: 0">
${res.join("")}
</svg>
`
);
},
};
};
使用插件
在vite.config.js中使用插件
export default defineConfig({
// 配置需要使用的插件列表,这里将vue添加进去
plugins: [
vue(),
svgBuilder("./src/components/svgIcon/svg/"),
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
})
],
})
使用SvgIcon组件
代码
<svg-icon iconName="home"/>
<svg-icon iconName="menu"/>
<svg-icon iconName="list" :width="30" :height="30" color="red"/>
效果

本文介绍了如何在Vue3项目中利用vite构建一个SVG图标组件库。首先展示了SvgIcon.vue组件的代码,该组件通过`<use>`标签引用SVG符号来显示图标。接着,在main.js中全局注册了SvgIcon组件。然后,创建了一个svgBuilder.js插件,该插件读取SVG文件并转换为`<symbol>`标签,插入到HTML文档中。最后,在vite.config.js中使用svgBuilder插件,并展示了几个使用SvgIcon组件的例子。

810

被折叠的 条评论
为什么被折叠?



