衔接上一篇文章,这一篇继续写我在那个项目的优化,大图的svg我通过了img src引入了项目,可是还有很多小的svg图标需要引入,如果在用img 引入 过多的网络请求造成不不必要的浪费,于是我有又开始作死了
svg-sprite-loader
因为我这个项目是 自己搭建的 webpack 使用的是vue框架,所以我很自然的想到 svg-sprite-loader 这个svg处理的神器,配置超级简单,基本度娘都有标准的写法,什么?还让我去百度,那我看你干嘛。 好吧兄弟们,好不多说看代码,我们只需要在 rules 中加入这个配置
{
test: /\.svg$/,
loader: 'svg-sprite-loader',
include:[path.resolve('src/asset/svgSprite')],
options:{
symbolId:'icon-[name]'
}
}
现在我给大家解释下每个的意思
path.resolve('src/asset/svgSprite') // 需要处理svg存放的目录,这个目录和我大图svg是分开的哦~
symbolId:'icon-[name]' 就是我们合并之后svg文件子类的id名称
下面给大家看下项目run 之后的截图就了解了
红色箭头所指就是我svg文件名 icon 是后来追加上去的 等等先别走,还有一点就完事了,你要关掉了后面的内容咋看。注意如果项目中还用了 url-loader 那么还需要加一段代码{
test: /\.(png|jpg|gif|webp|woff|eot|ttf|svg)$/,
use:{
loader:'url-loader',
options:{
name:'img/[name].[ext]',
limit:3000
}
},
exclude:[path.resolve('src/asset/svgSprite')] // 这里是需要加的,意思是不处理这个文件
},
这样webpack的配置文件就修改完成了 接下来在 components 里面创建一个文件夹 例如我的文件名称是 svgIcon 里面创建两个文件 index.ts 和 svgIcon.vue 下面我放的是 vue+ts版的代码,如果大家项目没有用呢也不要灰心,我还会放一个普通版的
ts版
<template>
<svg :class="svgClass"
:style="{
'width':`${width}rem`,
'height':`${height}rem`
}"
aria-hidden="true" >
<use :xlink:href="iconName" ref="svgRefs"></use>
</svg>
</template>
<script lang="ts">
import Vue from 'vue';
import { Component, Prop} from 'vue-property-decorator';
@Component
export default class svgIcon extends Vue {
name:string = 'svg-icon'
@Prop(String) iconClass ;
@Prop(String) className ;
@Prop(Number) width ;
@Prop(Number) height ;
get iconName():string {
return `#icon-${this.iconClass}`
}
get svgClass(): string{
if (this.className) {
return 'svg-icon ' + this.className
} else {
return 'svg-icon'
}
}
}
</script>
<style scoped>
.svg-icon {
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
</style>
普通版
svgIcon.vue
<template>
<svg :class="svgClass"
:style="{
'width':`${width}rem`,
'height':`${height}rem`
}"
aria-hidden="true" >
<use :xlink:href="iconName" ref="svgRefs"></use>
</svg>
</template>
<script>
export default {
name: 'svg-icon',
props: {
iconClass: {
type: String,
required: true
},
className: {
type: String
},
width:{
type:Number
},
height:{
type:Number
}
},
computed: {
iconName() {
return `#icon-${this.iconClass}`
},
svgClass() {
if (this.className) {
return 'svg-icon ' + this.className
} else {
return 'svg-icon'
}
}
},
mounted(){
}
}
</script>
<style scoped>
.svg-icon {
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
</style>
最后是 index文件的内容
index.js
import Vue from 'vue'
import SvgIcon from './svgIcon.vue'
Vue.component('svg-icon',SvgIcon);
const requireAll = requireContext =>
{
requireContext.keys().map(requireContext)
}
const req = require.context('./../../asset/svgSprite', false, /\.svg$/)
requireAll(req)
关于 require.context 是webpack导入文件的一种写法,只能在webpack项目中用 最后在 vue项目的入口文件中加一句话就ok啦
import './components/svgIcon'
最后给大家举个使用例子 因为我们是全局注册了所以用的时候只要像下面这样就可以啦
<svg-icon class="lls" icon-class="jingjingyeye" :width="4.46" :height="2.05"></svg-icon>
为啥这就可以了呢?我自问自答下,因为我们开始在webpack中的配置他把我们的svg全部注入到了我们index.html 的 body 中了。看完随手左侧小手下,有问题大家就留言。看到我会回复的。
尾
使用这种方式的好处不言而喻,唯一值得注意的问题就是我们要注意svg的大小,如果文件太大就不要用了,毕竟这是把svg直接注入到index.html中的