feat: 交互优化与代码质量改进
- SvgIcon 改为 PNG 图标方案,组件重命名为 Icon - 修复 TransactionItem tap 事件名冲突,改为 item-tap - 修复 Stats 页面切换 tab 时 overview 不更新 - 修复 CategoryIcon bgColor 必填问题 - 修复 ChartWrapper import 顺序 - 修复 budget onDelete 空字符串问题 - 清理 profile 页面未使用 CSS - 统一所有页面 header 为 sticky 定位 - 修复导航栏返回按钮不统一 - 添加导出功能 loading 状态 - 优化 scroll-into-view 延迟
This commit is contained in:
90
client/src/components/Icon/Icon.vue
Normal file
90
client/src/components/Icon/Icon.vue
Normal file
@@ -0,0 +1,90 @@
|
||||
<template>
|
||||
<image v-if="iconSrc" class="icon" :src="iconSrc" :style="sizeStyle" mode="aspectFit" />
|
||||
<view v-else class="icon-fallback" :style="sizeStyle">?</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
name: string
|
||||
size?: number
|
||||
color?: string
|
||||
}>(), { size: 40, color: '#2D1B1B' })
|
||||
|
||||
// 图标路径映射表:name + color -> PNG 文件路径
|
||||
const iconMap: Record<string, Record<string, string>> = {
|
||||
arrowLeft: {
|
||||
'#2D1B1B': '/static/icons/arrow-left-dark.png',
|
||||
'#8B7E7E': '/static/icons/arrow-left-gray.png',
|
||||
},
|
||||
arrowRight: {
|
||||
'#8B7E7E': '/static/icons/arrow-right-gray.png',
|
||||
'#E0D6D0': '/static/icons/arrow-right-pale.png',
|
||||
},
|
||||
calendar: {
|
||||
'#8B7E7E': '/static/icons/calendar-gray.png',
|
||||
},
|
||||
edit: {
|
||||
'#8B7E7E': '/static/icons/edit-gray.png',
|
||||
'#BFB3B3': '/static/icons/edit-light.png',
|
||||
},
|
||||
'alert-circle': {
|
||||
'#BFB3B3': '/static/icons/alert-circle-light.png',
|
||||
},
|
||||
user: {
|
||||
'#8B7E7E': '/static/icons/user-gray.png',
|
||||
'#FFFFFF': '/static/icons/user-white.png',
|
||||
},
|
||||
bell: {
|
||||
'#8B7E7E': '/static/icons/bell-gray.png',
|
||||
},
|
||||
'trend-down': {
|
||||
'#FF6B6B': '/static/icons/trend-down-red.png',
|
||||
},
|
||||
'trend-up': {
|
||||
'#7BC67E': '/static/icons/trend-up-green.png',
|
||||
},
|
||||
chevronRight: {
|
||||
'#BFB3B3': '/static/icons/chevron-right-light.png',
|
||||
},
|
||||
check: {
|
||||
'#FFFFFF': '/static/icons/check-white.png',
|
||||
},
|
||||
trash: {
|
||||
'#FF8C69': '/static/icons/trash-orange.png',
|
||||
'#FF6B6B': '/static/icons/trash-red.png',
|
||||
'#FFFFFF': '/static/icons/trash-white.png',
|
||||
},
|
||||
}
|
||||
|
||||
const iconSrc = computed(() => {
|
||||
const variants = iconMap[props.name]
|
||||
if (!variants) {
|
||||
console.warn(`[Icon] 图标 "${props.name}" 不存在`)
|
||||
return ''
|
||||
}
|
||||
// 精确匹配颜色,找不到则使用第一个变体
|
||||
return variants[props.color] || Object.values(variants)[0] || ''
|
||||
})
|
||||
|
||||
const sizeStyle = computed(() => {
|
||||
const s = props.size + 'rpx'
|
||||
return { width: s, height: s }
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.icon {
|
||||
display: inline-block;
|
||||
}
|
||||
.icon-fallback {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #F0E0D6;
|
||||
border-radius: 4rpx;
|
||||
color: #BFB3B3;
|
||||
font-size: 20rpx;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user