列表生命周期:入场、出场、重排
一个会动的列表要同时处理三件事:新项入场 (enter)、旧项出场 (exit)、顺序变化时各项重排
(reorder)。三者各有难点——入场要在挂载瞬间从初态过渡到终态;出场最棘手,因为 DOM 一旦
removeChild 就不复存在,必须先播完出场动画、再真正卸载 (即 AnimatePresence 的延后卸载);
重排则不能直接对位置做动画 (会逐帧重排),需用 FLIP 只动 transform。
点下面的按钮观察三种过渡。
添加 = fade+slide 入场 · 删除 = 先播出场再卸载 · 打乱 = FLIP 平移到新位
当前项数 0
removeChild,元素当帧消失,动画无从播起。
AnimatePresence 的做法是延后卸载:先把待删项标记为「正在离开」、对它播一段出场动画,
在 onComplete 里才执行真正的 removeChild。这段时间该项仍在 DOM 中,只是不再可交互。
getBoundingClientRect);其二 Last,改完 DOM 顺序后量新 rect;其三 Invert,
用一个 transform 把元素反推回旧位,看起来像没动;其四 Play,把这个 transform 动画归零,
元素便从旧位平滑滑到新位。整个过程只动 transform,不触发重排。
三者的区别在于动画与 DOM 变更的先后:入场是「先插入 DOM,再从初态动到终态」;出场是「先动到初态,
动完再移出 DOM」;重排是「DOM 先就位 (新顺序),再用 transform 反推后归零」。它们都由同一个
Animation 驱动,差别只在 mutate 与 onComplete 的时机。
@vega/anim — 出场的延后卸载 + 重排的 FLIP