1. 问题现象与背景
上周在开发社交应用的分享功能时,遇到了一个奇怪的动画问题。当用户点击"分享给好友"按钮时,会从底部弹出一个半屏窗口,展示微信、微博等分享渠道。这个功能使用的是bindSheet半模态弹窗,开发过程很顺利,但在测试关闭弹窗时发现了异常现象。
具体表现为:当用户点击弹窗外的空白区域(蒙层)试图关闭它时,弹窗的退出动画(向下滑出的效果)会明显地执行两次。视觉上看起来就像弹窗先"闪"了一下,然后才彻底消失,给人一种卡顿、不流畅的感觉。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 问题分析与定位
2.1 初步排查
首先检查了动画相关的代码,确认动画配置没有问题。尝试用.show方法直接控制弹窗显示/隐藏,问题依然存在。进一步观察发现,这个问题在快速操作时尤为明显。
2.2 深入分析
通过仔细检查代码结构,发现问题出在ForEach循环中的bindSheet绑定方式上。在列表组件中,我们为每个ListItem都绑定了同一个ShareBuilder构造器和同一个isShow控制变量。
这种实现方式导致了一个严重的问题:当用户点击"分享"按钮时,实际上创建了多个完全相同的半模态窗口实例,它们重叠显示在屏幕上。由于这些实例完全重叠,用户看起来只有一个弹窗。
2.3 问题重现流程
- 用户点击"分享给好友"项,
onClick事件将isShow设为true - 由于
ForEach循环,所有ListItem子组件都绑定了bindSheet - 当
isShow变为true,所有绑定关系同时生效,创建了N个完全相同的半模态窗口 - 用户点击蒙层关闭时,最顶层的窗口先响应,执行退出动画并关闭
- 通过
$$双向绑定,isShow被设为false - 这个变化触发了剩余(N-1)个弹窗实例的关闭指令
- 用户看到第一个窗口关闭后,又有一批窗口开始执行退出动画
3. 解决方案
3.1 核心思路
问题的本质是一个控制变量被多个组件监听,导致多个弹窗实例的连锁创建与销毁。解决方案的关键是打破"一个变量,多个绑定"的错误模式,确保bindSheet只在真正需要弹窗的组件上生效。
3.2 具体实现
使用条件判断语句(三元表达式),只为特定的数据项绑定
