核心是用@tap绑定爱心容器而非图片,通过CSS关键帧实现三段式动画,配合状态同步与多端适配。需避免事件穿透、动画堆积、class残留及缓存丢失问题。

点击图片触发爱心动画的 DOM 结构和事件绑定
核心是用 @tap(不是 @click)监听图片区域,避免 iOS 点击延迟和部分安卓 touch 事件穿透问题。图片本身不能设 pointer-events: none,否则动画元素会收不到事件冒泡;但爱心图标要绝对定位在图片上层,且需独立响应 tap —— 所以建议把爱心图标配成一个透明按钮或 view 覆盖在右下角,再通过 z-index 控制层级。
常见错误:直接给 image 组件加 @tap 后,在某些 Android 机型上点不中;或把爱心动画写在 image 内部导致渲染异常。
- 用
view包裹image,再在同级放一个view作为爱心容器(position: absolute; right: 20rpx; bottom: 20rpx;) - 爱心容器内放一个
image或自定义 iconfont 图标,初始opacity: 0; transform: scale(0.5); - 绑定
@tap="handleLike"到爱心容器,不是图片本身
uni-app 中用 CSS 动画实现“放大 + 变色 + 上浮”三段式爱心效果
uni-app 的 animation API 在 H5 和小程序平台兼容性差,尤其 iOS 微信小程序对 transform: scale() + opacity 同时动画支持不稳定。更可靠的做法是纯 CSS 关键帧动画 + class 切换,配合 animation-fill-mode: forwards 锁定结束态。
注意:不能用 transition 模拟,因为需要一次性播放、不可中断、且要支持多次快速点击(否则动画队列堆积)。
- 定义动画:
@keyframes like-burst { 0% { opacity: 1; transform: scale(1) translateY(0); } 50% { opacity: 0.9; transform: scale(1.4) translateY(-30rpx); } 100% { opacity: 0; transform: scale(1.8) translateY(-60rpx); } } - 爱心容器添加类
like-active,该类含animation: like-burst 0.4s ease-out; - 动画结束后手动移除类(用
setTimeout或animationend事件),否则下次点击无法再次触发动画
点赞状态同步与防重复点击
用户可能连点、误点,或网络未返回就二次点击。不能只靠 UI 动画反馈,必须控制逻辑层:点赞状态变更、接口调用节流、本地缓存标记。
常见坑:动画播完才发请求,导致视觉反馈滞后;或没做 loading 状态拦截,造成同一张图被连续提交多次点赞。
- 点击后立即设置
isLiked = !isLiked并触发动画,同时禁用该爱心容器的@tap(比如加v-if或用disabled样式遮罩) - 用
uni.showLoading或局部 loading 状态防止重复操作,但不要等接口返回才开启动画 - 点赞成功后更新本地缓存(
uni.setStorageSync),下次进入页面可读取初始状态 - 失败时回滚
isLiked并提示,但动画不重播(已播过一次)
小程序平台特殊处理:iOS 微信里动画卡顿、安卓真机缩放失真
微信小程序基础库 2.25+ 对 transform 的硬件加速支持仍有限,尤其 scale 配合 translateY 在低端安卓机容易掉帧;iOS 则常因视口缩放导致 rpx 计算偏移,爱心飘出屏幕。
最稳妥的适配方式是放弃纯 CSS 动画,改用 uni.createAnimation 创建 canvas 级动画,但成本高;折中方案是降级动画复杂度 + 加 fallback。
- 安卓端若检测到
uni.getSystemInfoSync().platform === 'android',把动画时长从 400ms 改为 300ms,减少卡顿感 - iOS 下用
px替代rpx定义爱心位移(如transform: translateY(-40px)),避免 rpx 缩放误差 - 动画结束后加一层
opacity: 0; height: 0; overflow: hidden;清理 DOM,防止残留空白占位



















