前情回顾
公司想搞一套特色的图标库,不想使用antd组件自带的图标库。 于是封装了一个使用UI提供的svg图标的组件。
活不多说,直接上代码:
<template>
<div
class="svg-icon-box"
:style="{width: size + 'px', height: size + 'px', 'line-height': size + 'px', cursor: cursor ? 'pointer' : 'auto', overflow: 'hidden'}"
@mouseover="changeImageColor(true)"
@mouseleave="changeImageColor(false)"
@click="clickFun($event)"
>
<svg
:class="svgClass"
aria-hidden="true"
:style="{
fontSize: size + 'px',
filter: self ? 'none' : 'drop-shadow(' + iconColor + ' 0px -1000px)',
transform: self ? 'none' : 'translate(0px, 1000px)'
}">
<use :xlink:href="iconName"/>
</svg>
</div>
</template>
<script>
export default {
name: 'YIcon',
props: {
type: {
type: String,
required: true
},
className: {
type: String,
default: ''
},
color: {
type: String,
default: '#5D6E7F'
},
size: {
type: [Number, String],
default: 16
},
cursor: {
type: [Boolean, String, Number],
default: false
},
hover: {
type: String,
default: ''
},
self: {
type: [Boolean, String, Number],
default: false
},
},
data() {
return {
isHover: false
}
},
computed: {
iconColor() {
return this.isHover ? this.hover || this.color : this.color
},
iconName() {
return this.type.startsWith('icon-') ? `#${this.type}` : `#icon-${this.type}`
},
svgClass() {
if (this.className) {
return 'svg-icon ' + this.className
} else {
return 'svg-icon'
}
}
},
methods: {
changeImageColor(flag) {
if (this.self) return
this.isHover = flag
},
clickFun(e) {
this.$emit('click', e)
}
}
}
</script>
<style scoped>
.svg-icon-box {
display: inline-block;
vertical-align: middle;
}
.svg-icon {
width: 1em;
height: 1em;
/* vertical-align: -0.15em; */
fill: currentColor;
overflow: hidden;
}
</style>
由于UI制作的svg,其中的fill属性都是固定值,我们用组件引用的时候,无法直接修改图标的颜色。
所以,看上图代码,我采用了迂回的方式,使用filter:drop-shadow投影出图标样式,然后设置颜色,再将原图通过transform:translate(0px, 1000px)和外层overflow: 'hidden'移出可视范围。在Chrome上测试很OK!
于是兴奋地提交了代码,部署到测试环境,用了个把月,很OK!
天有不测风云,有个领导电脑上,看页面时图标出现莫名其妙的BUG,显示不出现,然后鼠标悬浮又出现,移开鼠标,或者滚动鼠标都会出现闪现的BUG,关键是只有他电脑有问题,其他人电脑上都是没问题的,一阵定位,毫无头绪!
开始,看这现象就是有东西遮挡,然后各种控制台调试,就是找不到遮挡的元素!
Two thousand years later 。。。
在本地先是安装了低版本Firefox,问题未复现,然后安装了高版本Firefox,问题必现了!
对开发来说,找到必现条件,问题就解决了一半了。
然后,本地电脑上也没有找到遮挡的元素。。。
方向肯定是错了,一开始我也没想到是filter:drop-shadow的浏览器支持问题,毕竟还是展示了,但我尝试过去除这个属性之后,就没有这个问题了。
于是,我敲定就是这个样式在高版本Firefox上的支持有问题。
解决方案
不能使用filter:drop-shadow样式
需要改变svg颜色
那只能修改svg代码,将fill=“具体色值”的属性,改成fill="currentColor"
然后去找UI小姐姐,想让她制作svg图标的时候,直接就用这个值,然后失望了。。。
UI小姐姐制作svg时毕竟不是直接写代码,这个值只能设置某个色值或者none
所以,只有拿到图标后全局替换了。
好在问题解决了。
代码如下
<template>
<div
class="svg-icon-box"
:style="{
width: size + 'px',
height: size + 'px',
'line-height': size + 'px',
cursor: cursor ? typeof cursor === 'string' ? cursor : 'pointer' : 'auto',
overflow: 'hidden'
}"
@mouseover="changeImageColor(true)"
@mouseleave="changeImageColor(false)"
@click="clickFun($event)"
>
<svg
:class="svgClass"
aria-hidden="true"
:style="{
fontSize: size + 'px',
fill: 'currentColor',
color: iconColor
}">
<use :xlink:href="iconName"/>
</svg>
</div>
</template>
<script>
export default {
name: 'YIcon',
props: {
type: {
type: String,
required: true
},
className: {
type: String,
default: ''
},
color: {
type: String,
default: '#5D6E7F'
},
size: {
type: [Number, String],
default: 16
},
cursor: {
type: [Boolean, String],
default: false
},
hover: {
type: String,
default: ''
},
self: {
type: [Boolean, String, Number],
default: false
},
},
data() {
return {
isHover: false
}
},
computed: {
iconColor() {
return this.isHover ? this.hover || this.color : this.color
},
iconName() {
return this.type.startsWith('icon-') ? `#${this.type}` : `#icon-${this.type}`
},
svgClass() {
if (this.className) {
return 'svg-icon ' + this.className
} else {
return 'svg-icon'
}
}
},
methods: {
changeImageColor(flag) {
if (this.self) return
this.isHover = flag
},
clickFun(e) {
this.$emit('click', e)
}
}
}
</script>
<style scoped>
.svg-icon-box {
display: inline-block;
vertical-align: middle;
}
.svg-icon {
width: 1em;
height: 1em;
/* vertical-align: -0.15em; */
fill: currentColor;
overflow: hidden;
}
</style>
当然,使用UI小姐姐提供的svg图标库,还需要在main.js中做一些配置,还有webpack配置,由于跟本篇想要表达的问题无关就不赘述了,有兴趣的朋友,可以上网搜搜,或者留言,我加更!
如果读此文章有收获,希望帮忙点个赞,也可以留言互相学习,谢谢各位老铁!