feat: v1.3 交互增强

新增功能:
- 账单左滑删除(替代长按,更符合移动端习惯)
- 输入震动反馈(Numpad 按键时调用 uni.vibrateShort)
- 保存成功动画(Checkmark 弹出动画)
- 分类图标滚动到选中项(编辑记录时自动定位)

组件更新:
- TransactionItem 支持左滑露出删除按钮
- Numpad 添加震动反馈
- SaveSuccess 新增保存成功动画组件
This commit is contained in:
2026-05-29 16:35:31 +08:00
parent 7f8b301f95
commit 35bfe8293a
5 changed files with 196 additions and 16 deletions

View File

@@ -0,0 +1,85 @@
<template>
<view class="save-success" v-if="visible" @tap="hide">
<view class="success-icon" :class="{ show: animating }">
<SvgIcon name="check" :size="80" color="#FFFFFF" />
</view>
<text class="success-text" :class="{ show: animating }">{{ text }}</text>
</view>
</template>
<script setup lang="ts">
import { ref, watch } from 'vue'
import SvgIcon from '@/components/SvgIcon/SvgIcon.vue'
const props = withDefaults(defineProps<{
visible: boolean
text?: string
}>(), { text: '保存成功' })
const emit = defineEmits(['update:visible'])
const animating = ref(false)
watch(() => props.visible, (val) => {
if (val) {
setTimeout(() => { animating.value = true }, 50)
setTimeout(() => { hide() }, 2000)
} else {
animating.value = false
}
})
function hide() {
animating.value = false
setTimeout(() => { emit('update:visible', false) }, 300)
}
</script>
<style lang="scss" scoped>
.save-success {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background: rgba(0, 0, 0, 0.5);
z-index: 9999;
}
.success-icon {
width: 160rpx;
height: 160rpx;
border-radius: 50%;
background: linear-gradient(135deg, #7BC67E, #5BA85E);
display: flex;
align-items: center;
justify-content: center;
transform: scale(0);
opacity: 0;
transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
&.show {
transform: scale(1);
opacity: 1;
}
}
.success-text {
font-size: 32rpx;
font-weight: 600;
color: #FFFFFF;
margin-top: 24rpx;
transform: translateY(20rpx);
opacity: 0;
transition: all 0.3s ease 0.2s;
&.show {
transform: translateY(0);
opacity: 1;
}
}
</style>