动画引擎原理 总览待审核
enter · exit · reorder · AnimatePresence

列表生命周期:入场、出场、重排

一个会动的列表要同时处理三件事:新项入场 (enter)、旧项出场 (exit)、顺序变化时各项重排 (reorder)。三者各有难点——入场要在挂载瞬间从初态过渡到终态;出场最棘手,因为 DOM 一旦 removeChild 就不复存在,必须先播完出场动画、再真正卸载 (即 AnimatePresence 的延后卸载); 重排则不能直接对位置做动画 (会逐帧重排),需用 FLIP 只动 transform。 点下面的按钮观察三种过渡。

添加 = fade+slide 入场 · 删除 = 先播出场再卸载 · 打乱 = FLIP 平移到新位

    当前项数 0
    出场为何不能直接删:删除一项时若立即 removeChild,元素当帧消失,动画无从播起。 AnimatePresence 的做法是延后卸载:先把待删项标记为「正在离开」、对它播一段出场动画, 在 onComplete 里才执行真正的 removeChild。这段时间该项仍在 DOM 中,只是不再可交互。 FLIP 四步 (First / Last / Invert / Play):其一 First,改动前记录每项的旧 rect (getBoundingClientRect);其二 Last,改完 DOM 顺序后量新 rect;其三 Invert, 用一个 transform 把元素反推回旧位,看起来像没动;其四 Play,把这个 transform 动画归零, 元素便从旧位平滑滑到新位。整个过程只动 transform,不触发重排。

    三者的区别在于动画与 DOM 变更的先后:入场是「先插入 DOM,再从初态动到终态」;出场是「先动到初态, 动完再移出 DOM」;重排是「DOM 先就位 (新顺序),再用 transform 反推后归零」。它们都由同一个 Animation 驱动,差别只在 mutate 与 onComplete 的时机。

    @vega/anim — 出场的延后卸载 + 重排的 FLIP
    
      

    FLIP 的几何反推与更复杂的共享布局过渡见高级交互;入场 / 出场用到的多关键帧 与逐段缓动见关键帧