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.
126 lines
2.6 KiB
126 lines
2.6 KiB
<template>
|
|
<div
|
|
class="svg-icon-wrapper"
|
|
:style="{ width: size + 'px', height: size + 'px' }"
|
|
@click="handleClick"
|
|
@mouseenter="isHovered = true"
|
|
@mouseleave="isHovered = false"
|
|
>
|
|
<div
|
|
class="svg-icon"
|
|
v-html="svgContent"
|
|
:style="{
|
|
'--icon-color': isHovered ? hoverColor : color,
|
|
'--icon-hover-color': hoverColor
|
|
}"
|
|
></div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
name: 'SvgIcon',
|
|
props: {
|
|
// SVG文件路径(必须)
|
|
path: {
|
|
type: String,
|
|
required: true,
|
|
validator: value => value.endsWith('.svg')
|
|
},
|
|
// 图标大小(像素)
|
|
size: {
|
|
type: Number,
|
|
default: 24
|
|
},
|
|
// 默认颜色
|
|
color: {
|
|
type: String,
|
|
default: '#333333'
|
|
},
|
|
// 悬停颜色
|
|
hoverColor: {
|
|
type: String,
|
|
default: '#409EFF'
|
|
},
|
|
// 禁用状态
|
|
disabled: {
|
|
type: Boolean,
|
|
default: false
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
svgContent: '',
|
|
isHovered: false
|
|
}
|
|
},
|
|
watch: {
|
|
path: {
|
|
immediate: true,
|
|
handler: 'loadSvg'
|
|
}
|
|
},
|
|
methods: {
|
|
async loadSvg() {
|
|
try {
|
|
// 使用动态import加载SVG文件
|
|
const response = await fetch(this.path)
|
|
if (!response.ok) throw new Error('SVG加载失败')
|
|
this.svgContent = await response.text()
|
|
|
|
// 如果SVG中有fill属性,替换为currentColor以便CSS控制
|
|
this.svgContent = this.svgContent.replace(/fill="[^"]*"/g, 'fill="currentColor"')
|
|
} catch (error) {
|
|
console.error('加载SVG图标失败:', error)
|
|
this.svgContent = ''
|
|
}
|
|
},
|
|
handleClick(event) {
|
|
if (!this.disabled) {
|
|
this.$emit('click', event)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.svg-icon-wrapper {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
cursor: pointer;
|
|
transition: all 0.3s;
|
|
}
|
|
|
|
.svg-icon-wrapper:hover {
|
|
opacity: 0.8;
|
|
}
|
|
|
|
.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-wrapper[disabled] {
|
|
cursor: not-allowed;
|
|
opacity: 0.5;
|
|
}
|
|
|
|
.svg-icon >>> path {
|
|
fill: currentColor;
|
|
}
|
|
|
|
.svg-icon >>> circle {
|
|
fill: currentColor;
|
|
}
|
|
</style>
|