ahutchen's picture
fix
40f23a9
<template>
<i
:class="iconClass"
:style="iconStyle"
@click="handleClick"
></i>
</template>
<script setup>
import { computed } from 'vue'
const props = defineProps({
// 图标名称(FontAwesome类名,不需要前缀)
name: {
type: String,
required: true
},
// 图标大小
size: {
type: [String, Number],
default: 'inherit'
},
// 图标颜色
color: {
type: String,
default: 'inherit'
},
// 是否可点击
clickable: {
type: Boolean,
default: false
},
// 旋转角度
rotate: {
type: [String, Number],
default: 0
},
// 是否加载中(旋转动画)
loading: {
type: Boolean,
default: false
}
})
const emit = defineEmits(['click'])
// 图标类名
const iconClass = computed(() => {
const classes = []
// 基础类名
if (props.name.startsWith('fa-')) {
classes.push('fas', props.name)
} else {
classes.push('fas', `fa-${props.name}`)
}
// 可点击样式
if (props.clickable) {
classes.push('icon-clickable')
}
// 加载动画
if (props.loading) {
classes.push('fa-spin')
}
return classes.join(' ')
})
// 图标样式
const iconStyle = computed(() => {
const styles = {}
// 大小
if (props.size !== 'inherit') {
const sizeValue = typeof props.size === 'number' ? `${props.size}px` : props.size
styles.fontSize = sizeValue
}
// 颜色
if (props.color !== 'inherit') {
styles.color = props.color
}
// 旋转
if (props.rotate && !props.loading) {
styles.transform = `rotate(${props.rotate}deg)`
}
return styles
})
// 处理点击事件
const handleClick = (event) => {
if (props.clickable) {
emit('click', event)
}
}
</script>
<style scoped>
.icon-clickable {
cursor: pointer;
transition: var(--transition-fast);
user-select: none;
}
.icon-clickable:hover {
opacity: 0.8;
transform: scale(1.05);
}
.icon-clickable:active {
transform: scale(0.95);
}
/* 常用图标预设 */
.fa-play {
margin-left: 2px; /* 播放图标视觉居中 */
}
.fa-heart {
color: #e53e3e;
}
.fa-heart.far {
color: var(--text-secondary);
}
.fa-star {
color: #ed8936;
}
.fa-star.far {
color: var(--text-secondary);
}
/* 加载动画优化 */
.fa-spin {
animation: fa-spin 1s infinite linear;
}
@keyframes fa-spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
/* 无障碍支持 */
.icon-clickable:focus-visible {
outline: 2px solid var(--accent-red);
outline-offset: 2px;
border-radius: 2px;
}
/* 禁用状态 */
.icon-disabled {
opacity: 0.3;
cursor: not-allowed;
pointer-events: none;
}
</style>