You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
175 lines
4.0 KiB
175 lines
4.0 KiB
<template>
|
|
<div class="svg-icon-wrapper" :style="wrapperStyle" @mouseenter="handleMouseEnter" @mouseleave="handleMouseLeave">
|
|
<div class="svg-icon" v-html="svgContent" :style="{
|
|
'--icon-color': (hoverEffect || isActive) ? activeColor : defaultColor,
|
|
'--icon-hover-color': activeColor
|
|
}"></div>
|
|
<!-- :style="iconStyle" -->
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
name: 'SvgIcon',
|
|
props: {
|
|
// 图标路径(必须)
|
|
iconPath: {
|
|
type: String,
|
|
required: true
|
|
},
|
|
// 默认颜色
|
|
defaultColor: {
|
|
type: String,
|
|
default: '#606266'
|
|
},
|
|
// 激活颜色(传入后才允许变色)
|
|
activeColor: {
|
|
type: String,
|
|
default: null
|
|
},
|
|
// 是否开启悬停变色
|
|
hoverEffect: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
// 图标大小
|
|
size: {
|
|
type: [String, Number],
|
|
default: '14px'
|
|
},
|
|
// 是否当前激活状态
|
|
isActive: {
|
|
type: Boolean,
|
|
default: false
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
svgContent: '',
|
|
isHovering: false,
|
|
currentColor: this.defaultColor
|
|
}
|
|
},
|
|
computed: {
|
|
wrapperStyle() {
|
|
return {
|
|
width: typeof this.size === 'number' ? `${this.size}px` : this.size,
|
|
height: typeof this.size === 'number' ? `${this.size}px` : this.size,
|
|
display: 'inline-flex',
|
|
alignItems: 'center',
|
|
justifyContent: 'center'
|
|
}
|
|
},
|
|
iconStyle() {
|
|
return {
|
|
width: '100%',
|
|
height: '100%',
|
|
color: this.currentColor,
|
|
transition: 'color 0.3s ease'
|
|
}
|
|
},
|
|
shouldChangeColor() {
|
|
return this.activeColor && (this.hoverEffect || this.isActive)
|
|
}
|
|
},
|
|
watch: {
|
|
isActive(newVal) {
|
|
console.log(newVal, 'newVal---');
|
|
if (this.shouldChangeColor) {
|
|
this.currentColor = newVal ? this.activeColor : this.defaultColor
|
|
console.log(this.currentColor, 'this.currentColor--');
|
|
}
|
|
},
|
|
defaultColor(newVal) {
|
|
if (!this.isHovering && !this.isActive) {
|
|
this.currentColor = newVal
|
|
}
|
|
},
|
|
activeColor() {
|
|
this.updateColorState()
|
|
}
|
|
},
|
|
methods: {
|
|
async loadSvg() {
|
|
try {
|
|
const response = await fetch(this.iconPath)
|
|
this.svgContent = await response.text()
|
|
this.processSvg()
|
|
} catch (error) {
|
|
console.error('Failed to load SVG:', error)
|
|
}
|
|
},
|
|
processSvg() {
|
|
// 确保SVG没有自带颜色,以便用CSS控制
|
|
this.$nextTick(() => {
|
|
const svgElement = this.$el.querySelector('svg')
|
|
if (svgElement) {
|
|
// 更彻底地移除颜色属性
|
|
svgElement.removeAttribute('fill')
|
|
svgElement.removeAttribute('style')
|
|
const paths = svgElement.querySelectorAll('path, circle, rect, polygon')
|
|
paths.forEach(el => {
|
|
el.removeAttribute('fill')
|
|
})
|
|
svgElement.style.fill = 'currentColor'
|
|
svgElement.style.width = '100%'
|
|
svgElement.style.height = '100%'
|
|
}
|
|
})
|
|
},
|
|
handleMouseEnter() {
|
|
this.isHovering = true
|
|
this.updateColorState()
|
|
},
|
|
handleMouseLeave() {
|
|
this.isHovering = false
|
|
this.updateColorState()
|
|
},
|
|
updateColorState() {
|
|
if (this.activeColor) {
|
|
if (this.isActive) {
|
|
this.currentColor = this.activeColor
|
|
} else {
|
|
this.currentColor = this.isHovering && this.hoverEffect ?
|
|
this.activeColor :
|
|
this.defaultColor
|
|
}
|
|
} else {
|
|
this.currentColor = this.defaultColor
|
|
}
|
|
}
|
|
},
|
|
created() {
|
|
this.loadSvg()
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.svg-icon-wrapper {
|
|
cursor: pointer;
|
|
}
|
|
|
|
|
|
.svg-icon {
|
|
width: 100%;
|
|
height: 100%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
color: var(--icon-color);
|
|
transition: color 0.3s;
|
|
}
|
|
|
|
.svg-icon:hover {
|
|
color: var(--icon-hover-color);
|
|
}
|
|
|
|
.svg-icon {
|
|
display: inline-flex;
|
|
}
|
|
|
|
.svg-icon>>>svg {
|
|
fill: currentColor;
|
|
}
|
|
</style>
|