在vue中使用svg
背景
svg作为矢量图,放大不失真,但是如果在vue文件中直接引入svg的话会导致vue文件过长,不友好。想要在组件中使用的时候使用下面的方式来引入svg
// svg-name的值就是svg图片的名称
<svg-icon svg-name="xueren" />
步骤
- 在
components
下创建SvgIcon.vue
文件,并引入assets/icons/svg
目录下的所有svg
<!-- svg组件 -->
<template>
<svg class="svg-icon" :class="svgClass" aria-hidden="true">
<use :xlink:href="iconName" />
</svg>
</template>
<script>
// https://webpack.docschina.org/guides/dependency-management/#requirecontext
const requireAll = (context) => context.keys().map(context);
// webapck提供的API: 获取某个路径下的所有匹配的资源
// 参数1:要搜索的目录,
// 参数2:是否需要搜索子目录
// 参数3:匹配的正则表达式
const req = require.context("../assets/icons/svg", false, /\.svg$/);
requireAll(req);
export default {
name: "SvgIcon",
props: {
// svg 的名称
svgName: {
type: String,
required: true,
},
},
computed: {
iconName() {
return `#icon-${this.svgName}`;
},
svgClass() {
if (this.svgName) {
return "svg-icon" + this.svgName;
} else {
return "svg-icon";
}
},
},
};
</script>
<style scoped>
.svg-icon {
width: 100px;
height: 100px;
fill: currentColor;
overflow: hidden;
}
</style>
- 将SvgIcon.vue 组件注册为全局组件
main.js
import SvgIcon from "@/components/SvgIcon.vue";
// 注册到全局
Vue.component("svg-icon", SvgIcon);
- 使用
svg-sprite-loader
loader对svg进行处理,配置vue.config.js
vue.config.js
const { defineConfig } = require("@vue/cli-service");
const path = require("path");
module.exports = defineConfig({
transpileDependencies: true,
chainWebpack: (config) => {
config.module
.rule("svg")
.exclude.add(path.resolve("src/assets/icons"))
.end();
config.module
.rule("icons")
.test(/\.svg$/)
.include.add(path.resolve("src/assets/icons"))
.end()
.use("svg-sprite-loader")
.loader("svg-sprite-loader")
.options({
symbolId: "icon-[name]",
})
.end();
},
});
- 组件中的使用
<svg-icon svg-name="xueren" />
<svg-icon svg-name="touxiang" />
最终效果:
总结
svg-sprite-loader 会将加载的svg定义成symbol 汇聚到一个