起因
el-button组件只有icon属性标签,不支持单独的slot,但是项目中的svg图标都用《svg-icon》封装起来了。想着自己用css引入svg图标,然后一直不显示。结果发现,svg-sprite-loader导致了整个svg源文件加载到了css代码中。陷入沉思……
一、为什么大家都用svg-sprite-loader去处理svg加载
其实这是老做法了,我发现在新的浏览器版本中,或者不为了兼容ie的话,那么没必要啊。用mask就可以了。并且能做到一样的功能,使用了反而会导致我上面发生的问题。
二、正确的按需加载svg图标。请不要用require.content了。
require.content会导致所有使用该api导入的资源,会加入到loader中,影响初始加载速度
require.content会导致所有使用该api导入的资源,会加入到loader中,影响初始加载速度
require.content会导致所有使用该api导入的资源,会加入到loader中,影响初始加载速度
重要的事情说三遍,是所有使用该api都会导致该问题!!!
正确的做法是使用import去加载svg图标。
三、使用svg-sprite-loader的正确方式和按需加载
1、vue.config.js
const resolve = (dir) => path.join(__dirname, dir) // 读取文件
// const svgRule = config.module.rule('svg')
// svgRule.uses.clear()
// svgRule.use('svg-sprite-loader').loader('svg-sprite-loader').options({
// symbolId: 'icon-[name]',
// })
2、svg-icon源码,vue3示例,vue2同理
index.js部分定义按需加载svg图片
// import svgList from './svgList' // svg图片名称数组
// 按需导入svg图片
/*svgList.forEach((name) => {
import(`@/components/SvgIcon/svg/${name}.svg`)
})*/
<template>
<svg v-on="$attrs" class="svg-icon" aria-hidden="true">
<use :xlink:href="`#icon-${name}`" />
</svg>
</template>
<script>
import { defineComponent } from 'vue'
export default defineComponent({
name: 'SvgIcon',
props: {
name: {
type: String,
default: 'assloss',
},
},
})
</script>
<style lang="scss" scoped>
// 实现样式控制变色
.svg-icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
</style>
四、采用mask替代上述方式,也不需要配置svg-sprite-loader
1、html部分
<div :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners" />
styleExternalIcon() {
return {
mask: `url(${require(`@/components/SvgIcon/svg/${this.iconClass}.svg`)}) no-repeat 50% 50%`,
'-webkit-mask': `url(${require(`@/components/SvgIcon/svg/${this.iconClass}.svg`)}) no-repeat 50% 50%`,
}
},
2、css
.svg-icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
.svg-external-icon {
background-color: currentColor;
mask-size: cover !important;
display: inline-block;
}
最后关于颜色和大小控制也完全可以做到用font-size和color控制。而且我也可以自己把图标再控制封装,然后放在el-button里面了。
五、总结
唉,早上发生的问题。感觉比较重要
1、采用了svg-sprite-loader会导致源文件加载,导致无法用css加载svg图片
2、不用呢兼容性下降。但是通用性高了很多。
看大家取舍吧