文件格式
svg下方对应 .svg
index.vue svg-icon 组件
< template>
< svg
: viewBox= "viewBox"
xmlns= "http://www.w3.org/2000/svg"
xmlns : xlink= "http://www.w3.org/1999/xlink"
ref= "svg"
class = "svg-icon"
: class = "className"
v- on= "$listeners"
: style= "{ width: width + 'em', height: height + 'em' }"
v- html= "iconContent"
> < / svg>
< / template>
< script>
export default {
name : 'SvgIcon' ,
props : {
iconClass : {
type : String,
required : true
} ,
className : {
type : String,
default : ''
} ,
width : {
type : Number,
default : 1
} ,
height : {
type : Number,
default : 1
}
} ,
data ( ) {
return {
iconContent : null ,
viewBox : '0 0 24 24' ,
test : ''
}
} ,
watch : {
iconClass ( ) {
this . loadIcon ( )
}
} ,
created ( ) {
this . loadIcon ( )
} ,
methods : {
loadIcon ( ) {
const fileName = ` ${ this . iconClass} .svg `
import ( ` @/icons/svg/ ${ fileName} ` ) . then ( ( content ) => {
const regexSymbol = / ([\s\S]*?)<\/symbol> / g
const svg = content. default. content. replace ( regexSymbol, '$2' )
this . test = content
const regexSvg = / ([\s\S]*?)<\/svg> / g
const match = regexSvg. exec ( svg)
this . iconContent = match[ 2 ]
const regexAttr = / /
const matchAttr = regexAttr. exec ( svg) [ 1 ] . trim ( )
const viewBoxReg = / viewBox="([^"]+)" /
const viewBoxValue = viewBoxReg. exec ( matchAttr) [ 1 ]
this . viewBox = viewBoxValue
} ) . catch ( ( err ) => {
console. log ( err)
} )
}
}
}
< / script>
< style scoped>
. svg- icon {
vertical- align: - 0 . 15em;
fill : currentColor ! important;
overflow : hidden;
}
< / style>
index.js 注册组件
import Vue from 'vue'
import SvgIcon from './index.vue'
Vue. component ( 'SvgIcon' , SvgIcon)
主要是这段
config. module. rule ( "svg" ) . exclude. add ( resolve ( "src/icons" ) ) . end ( ) ;
config. module
. rule ( "icons" )
. test ( / \.svg$ / )
. include. add ( resolve ( "src/icons" ) )
. end ( )
. use ( "svg-sprite-loader" )
. loader ( "svg-sprite-loader" )
. options ( {
symbolId : "icon-[name]" ,
} )
. end ( ) ;
安装npm i svg-sprite-loader
"svg-sprite-loader" : "^6.0.11" ,
补充 可以不看
vue.config.js 主要使用带svg的那一段 这是webapck5 的配置
const { defineConfig } = require("@vue/cli-service");
const speedMeasureWebpackPlugin = require("speed-measure-webpack-plugin"); // 编译速度分析
const smp = new speedMeasureWebpackPlugin();
const path = require("path");
const isProd = process.env.NODE_ENV === "production";
let plugins = [];
module.exports = defineConfig({
productionSourceMap: false,
transpileDependencies: true,
lintOnSave: false,
devServer: {
port: 8080,
open: true,
hot: true,
allowedHosts: 'all',
compress: true, // 是否启动压缩Gzip
client: {
overlay: {
errors: true,
warnings: false,
runtimeErrors: false
}
},
}
},
configureWebpack: smp.wrap({
devtool: isProd ? false : "eval", // source-map eval-cheap-module-source-map
cache: {
type: "filesystem",
allowCollectingMemory: true,
buildDependencies: {
config: [__filename],
},
},
plugins: plugins,
optimization: {
minimize: isProd,
splitChunks: {
chunks: "all",
cacheGroups: {
common: {
name: "chunk-common",
chunks: "initial",
minChunks: 2,
maxInitialRequests: 5,
minSize: 0,
priority: 1,
reuseExistingChunk: true,
enforce: true,
},
vendors: {
name: "chunk-vendors",
test: /[\\/]node_modules[\\/]/,
chunks: "initial",
priority: 2,
reuseExistingChunk: true,
enforce: true,
},
elementUI: {
name: "chunk-elementui",
test: /[\\/]node_modules[\\/]element-ui[\\/]/,
chunks: "all",
priority: 3,
reuseExistingChunk: true,
enforce: true,
},
vuedraggable: {
name: "chunk-vuedraggable",
test: /[\\/]node_modules[\\/]vuedraggable[\\/]/,
chunks: "all",
priority: 8,
reuseExistingChunk: true,
enforce: true,
},
zrender: {
name: "chunk-zrender",
test: /[\\/]node_modules[\\/]zrender[\\/]/,
chunks: "all",
priority: 10,
reuseExistingChunk: true,
enforce: true,
},
},
},
},
module: {
rules: [],
},
}),
chainWebpack(config) {
if (!isProd) {
config.optimization.minimizers.delete("terser");
config.optimization.minimizers.delete("css");
config.module
.rule("js")
.test(/\.jsx$/)
.exclude.add(/node_modules/)
.end();
config.module
.rule("jsEsbuild")
.test(/\.js$/)
.exclude.add(/node_modules/)
.end()
.use("esbuild")
.loader("esbuild-loader")
.options({
loader: "js",
target: "es2015",
})
.end();
}
config.module.rule("svg").exclude.add(resolve("src/icons")).end();
config.module
.rule("icons")
.test(/\.svg$/)
.include.add(resolve("src/icons"))
.end()
.use("svg-sprite-loader")
.loader("svg-sprite-loader")
.options({
symbolId: "icon-[name]",
})
.end();
config.plugin("html").tap((args) => {
const date = new Date().toLocaleString();
args[0].createDate = date;
return args;
});
},
});
function resolve(dir) {
return path.join(__dirname, dir);
}