vue工程使用svg图片,svg-sprite-loader缺陷,你们的按需加载svg是错误的。
起因
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" 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 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、不用呢兼容性下降。但是通用性高了很多。
看大家取舍吧
作者:海天酱油_htSauce
链接:https://juejin.cn/post/7017657405265674271