点赞动画需用uni.createanimation+局部状态控制,须避开列表重渲染中断、animation对象复用、android gpu加速缺失三大坑;核心是只改字段不换对象、绑定view容器、每次新建实例、加transform:translatez(0)、防抖及及时清空anidata。

直接用 uni.createAnimation + 局部状态控制就能实现,但必须避开三个高频翻车点:列表重渲染导致动画中断、animation 绑定对象被复用、Android 上 GPU 加速缺失。
为什么点赞动画一触发整个列表就抖?
本质是 Vue 响应式追踪断裂 —— 你点了某条笔记的赞,却用 this.list[index] = { ...item, isLiked: true } 替换了整个对象。Vue 失去对原对象的引用,v-for 触发全量 diff,DOM 重建,正在播放的动画瞬间销毁。
- 正确做法:只改字段,不换对象,比如
this.list[index].isLiked = !this.list[index].isLiked - 确保
list是从data()返回的响应式对象(uni-app 默认支持) - 别在
props或异步回调里直接赋值未声明的数组字段,否则响应式失效
animation 绑定到 <view></view> 还是 <text></text>?
只能绑定到 <view></view>、<scroll-view></scroll-view> 等容器级标签。绑到 <text></text> 或 <image></image> 上,动画数据会静默丢弃,控制台也不报错。
- 每个点赞按钮外层必须包一层独立
<view class="like-ani-wrapper"></view> -
:animation属性必须指向一个唯一 key(如aniData[index]或aniData[item.id]),不能共用同一个 ref - 每次点击都要调用新
uni.createAnimation()实例,不能复用旧实例再.step()
点赞 +1 数字飞入动画怎么写才不卡?
核心是 translateY + opacity + 定时清空,且 Android 必须加 GPU 提速。
- 动画配置建议:
uni.createAnimation({ duration: 400, timingFunction: 'ease-out' }) - 先
.translateY(-80).opacity(1).step(),再.translateY(0).opacity(0).step() - 导出后立即赋值:
this.aniData[item.id] = animation.export() - 500ms 后清空对应 key:
this.$nextTick(() => { this.aniData[item.id] = {} })(避免残留影响下次) - Android 卡顿?在 wrapper 的 class 里加
transform: translateZ(0)强制启用 GPU 渲染
多个点赞同时触发,动画会打架吗?
会。如果用户快速连点或滑动中误触多个,aniData 对象可能被覆盖,后触发的动画覆盖前一个,导致部分动画丢失。
- 加简单防抖:
if (this.isAnimating) return; this.isAnimating = true,动画结束再置false - 更稳妥的做法:每个动画用独立 timer ID,
clearTimeout旧定时器再设新定时器 - 乐观更新 UI(点下就改
isLiked和upCount),后端成功后再校验,别等接口返回才动 DOM
最易忽略的是:动画结束后没清空 aniData 对应字段,下次再点同一项,export() 返回的是空对象,动画就不播了 —— 这个细节在真机调试时才暴露,模拟器常表现正常。










