概述
安装svg-sprite-loader
npm install svg-sprite-loader -D
在components文件下创建svg文件,编写全局svg组件
<template>
<svg :class="svgClass" aria-hidden="true" v-on="$listeners">
<use :xlink:href="iconName" />
</svg>
</template>
<script setup lang="ts">
const props = defineProps({
iconClass: {
type: String,
required: true,
},
className: {
type: String,
default: '',
},
})
const svgClass = computed(() => {
if (props.className) {
return 'svg-icon ' + props.className
} else {
return 'svg-icon'
}
})
const iconName = computed(() => {
return `#icon-${props.iconClass}`
})
</script>
<style lang="less">
.svg-icon {
width: 1em;
height: 1em;
fill: currentColor;
vertical-align: middle;
}
</style>
在assets文件夹下创建icon,放入svg图片
main入口文件注册全局组件svg
import { createApp } from 'vue'
import App from './App.vue'
import svgIcon from './components/svgIcon.vue'
createApp(App).component('svg-icon', svgIcon).mount('#app');
手写config插件(重点)
// js
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) => {
// console.log(++i)
// console.log(dirent.name)
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)
// console.log(res.length)
// const res = []
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>
`
)
},
}
}
// ts
import { Plugin } from 'vite'
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): string[] {
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) => {
// console.log(++i)
// console.log(dirent.name)
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: string,
perfix = 'icon'
): Plugin => {
if (path === '') return
idPerfix = perfix
const res = findSvgFile(path)
// console.log(res.length)
// const res = []
return {
name: 'svg-transform',
transformIndexHtml(html): string {
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.文件中引入插件
import { svgBuilder } from './src/plugins/svgBuilder.js'
export default defineConfig({
plugins: [
...
// 这里已经将src/icons/svg/下的svg全部导入,无需再单独导入
svgBuilder('./src/assets/icons/svg/')
]
})
vue中引入:
<svg-icon class-name="add" icon-class="add" />
用法:icon-class 直接写svg图片名,然后想加样式的话,直接用class-name在vue文件中写样式即可。
附:svg图片获取方式
从阿里巴巴图库中找到自己想要的图标,点击下载,复制svg代码或者下载svg图片放入对一个文件夹即可。
https://www.iconfont.cn/
最后
以上就是缓慢马里奥为你收集整理的vue3 vite 使用svg图的全部内容,希望文章能够帮你解决vue3 vite 使用svg图所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复