在使用 svg 图片的时候,有一种做法是把 svg 图片转换成 vue 组件的方式,所以就写了个脚本批量进行了转换。
svg 图片转成 vue 组件示例
svg
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg t="1657009929175" class="icon" viewBox="0 0 1024 1024" version="1.1"
xmlns="http://www.w3.org/2000/svg" p-id="2743"
xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200">
<defs>
<style type="text/css">@font-face { font-family: feedback-iconfont; src: url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.woff2?t=1630033759944") format("woff2"), url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.woff?t=1630033759944") format("woff"), url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.ttf?t=1630033759944") format("truetype"); }
</style>
</defs>
<path d="M519.168 66.56L134.656 286.72v440.832l384.512 220.672 384.512-220.672v-440.32L519.168 66.56z m323.072 617.984l-323.072 181.76-323.072-181.76V320.512L519.168 138.24l323.072 181.76v364.544z" p-id="2744"></path>
<path d="M360.448 389.632c22.528 0 40.96 18.432 40.96 40.96s-18.432 40.96-40.96 40.96-40.96-18.432-40.96-40.96 18.432-40.96 40.96-40.96zM360.448 573.952c28.16 0 51.2 23.04 51.2 51.2s-23.04 51.2-51.2 51.2-51.2-23.04-51.2-51.2 23.04-51.2 51.2-51.2zM667.648 338.432c-33.792 0-61.44 27.648-61.44 61.44s27.648 61.44 61.44 61.44 61.44-27.648 61.44-61.44c0.512-34.304-27.136-61.44-61.44-61.44z m0 92.16c-16.896 0-30.72-13.824-30.72-30.72s13.824-30.72 30.72-30.72 30.72 13.824 30.72 30.72c0.512 16.896-13.312 30.72-30.72 30.72zM667.648 573.952c22.528 0 40.96 18.432 40.96 40.96s-18.432 40.96-40.96 40.96-40.96-18.432-40.96-40.96 18.432-40.96 40.96-40.96z" p-id="2745"></path>
<path d="M647.168 440.832h40.96v153.6h-40.96v-153.6zM621.568 421.888L645.12 455.68l-251.904 176.64-23.552-33.792 251.904-176.64z" p-id="2746"></path>
<path d="M339.968 440.832h40.96v153.6h-40.96v-153.6z" p-id="2747"></path>
</svg>
vue
<template>
<svg :width="width" :height="height" :fill="color" viewBox="0 0 1024 1024">
<path d="M519.168 66.56L134.656 286.72v440.832l384.512 220.672 384.512-220.672v-440.32L519.168 66.56z m323.072 617.984l-323.072 181.76-323.072-181.76V320.512L519.168 138.24l323.072 181.76v364.544z" p-id="2744"></path>
<path d="M360.448 389.632c22.528 0 40.96 18.432 40.96 40.96s-18.432 40.96-40.96 40.96-40.96-18.432-40.96-40.96 18.432-40.96 40.96-40.96zM360.448 573.952c28.16 0 51.2 23.04 51.2 51.2s-23.04 51.2-51.2 51.2-51.2-23.04-51.2-51.2 23.04-51.2 51.2-51.2zM667.648 338.432c-33.792 0-61.44 27.648-61.44 61.44s27.648 61.44 61.44 61.44 61.44-27.648 61.44-61.44c0.512-34.304-27.136-61.44-61.44-61.44z m0 92.16c-16.896 0-30.72-13.824-30.72-30.72s13.824-30.72 30.72-30.72 30.72 13.824 30.72 30.72c0.512 16.896-13.312 30.72-30.72 30.72zM667.648 573.952c22.528 0 40.96 18.432 40.96 40.96s-18.432 40.96-40.96 40.96-40.96-18.432-40.96-40.96 18.432-40.96 40.96-40.96z" p-id="2745"></path>
<path d="M647.168 440.832h40.96v153.6h-40.96v-153.6zM621.568 421.888L645.12 455.68l-251.904 176.64-23.552-33.792 251.904-176.64z" p-id="2746"></path>
<path d="M339.968 440.832h40.96v153.6h-40.96v-153.6z" p-id="2747"></path>
</svg>
</template>
<script>
export default {
props: {
width: Number,
height: Number,
color: String
}
}
</script>
转换的 node 脚本
// svg2vue.js
var fs = require('fs')
const ICON_COMP_PATH = './src/components/Icon/'
fs.readdir(ICON_COMP_PATH + '/svg', (err, files) => {
if (err) {
return console.error(err)
}
// 将 svg 转换成 vue 文件
files.forEach(file => {
fs.readFile(ICON_COMP_PATH + '/svg/' + file, (err, data) => {
if (err) {
return console.error(err)
}
const str = data.toString()
const regex = /<path[\s\S]+><\/path>/g
const paths = str.match(regex)
let template = `<template>
<svg :width="width" :height="height" :fill="color" viewBox="0 0 1024 1024">
`
if (Array.isArray(paths)) {
paths.forEach(path => {
template += `
${path}
`
})
}
template += `
</svg>
</template>
<script>
export default {
props: {
width: Number,
height: Number,
color: String
}
}
</script>
`
const filename = file.replace('.svg', '') // 获取文件名
fs.writeFile(
`${ICON_COMP_PATH}/components/${filename}.vue`,
template,
err => {
if (err) {
return console.error(filename + '转换失败', err)
}
console.log(filename + '转换成功')
}
)
})
})
// 生成注册 vue 组件的 js 文件
const registIconComponent = () => {
let template = "import Vue from 'vue'\n"
files.forEach(file => {
const filename = file.replace('.svg', '')
const componentName = filename.replace('-', '')
template += `import ${componentName} from './components/${filename}.vue'\n`
})
template += '\n'
files.forEach(file => {
const filename = file.replace('.svg', '')
const componentName = filename.replace('-', '')
template += `Vue.component('${filename}', ${componentName})\n`
})
fs.writeFile(ICON_COMP_PATH + '/register.js', template, err => {
if (err) {
return console.error(err)
}
console.log('register.js 注册代码重新生成!')
})
}
registIconComponent()
// 生成组件名称列表
const getIconList = () => {
let template = 'export default [\n'
files.forEach(file => {
const filename = file.replace('.svg', '')
template += ` '${filename}',\n`
})
template += ']\n'
fs.writeFile(ICON_COMP_PATH + '/icon-list.js', template, err => {
if (err) {
return console.error(err)
}
console.log('icon-list.js 注册代码重新生成!')
})
}
getIconList()
})
使用
执行 node 脚本:
node svg2vue.js
在入口文件 main.js
中导入注册文件:
import './components/Icon/register'
最后
不过这种方式需要在每次有新 svg 图片的时候执行命令。也可以通过 iconfont 来做到 svg 图片的管理。
网友评论