前端开发
在 Vue/Svelte/Nuxt…
在 Vue、Nuxt、Svelte、SvelteKit 或其他带 mount/unmount 生命周期的组件框架里,安全地创建并清理 GSAP 补间与 ScrollTrigger。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 49/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
在 Vue/Svelte/Nuxt 等有通用
解决思路
- 在组件的 mounted 生命周期之后创建 tweens 和 ScrollTrigger:Vue 用 onMounted,Svelte 用 onMount,确保容器 ref 已存在于 DOM;不要在组件 setup 或同步顶层脚本中创建(此时 DOM 节点可能还不存在)。
- 在 unmount 清理钩子中调用 ctx.revert():Vue 用 onUnmounted,Svelte 用 onMount 返回的清理函数,使该 context 内所有动画与 ScrollTrigger 被 kill、内联样式被还原,避免在已分离节点上运行和内存泄漏。
- 用 gsap.context(callback, scope) 并把组件根元素/ref 作为第二个参数传入:Vue 传 container.value,Svelte 传 bind:this={container} 拿到的 container,使回调内的 .box、.item 等选择器只在该子树内匹配。
- 把 tweens 和 ScrollTrigger 都写在同一个 gsap.context() 回调里,它们会被统一追踪,ctx.revert() 时一并被还原。
- Vue 3 Composition API:用 ref(null) 声明容器、模板绑定 ref="container",在 onMounted 中先做 if (!container.value) return; 再创建 context,onUnmounted 中执行 ctx?.revert()。
- Vue 3 <script setup>:使用同一套模式——onMounted 内建 context,onUnmounted 内 ctx?.revert(),模板里用 ref="container" 绑定根元素。
- 插件在应用级别注册一次(如 gsap.registerPlugin(ScrollTrigger) 放在 main.js),不要在每次渲染都会执行的组件体内重复注册。
- Nuxt 4:写一个可复用 composable(如 composables/useGSAP.ts),在其中统一注册插件并暴露 gsap、ScrollTrigger、lazyLoadPlugin 供组件调用。
- Nuxt 4:在 composable 中维护 PLUGINS 常量列表与 pluginMap 映射,每个插件写成 () => import("gsap/Xxx") 的动态导入(含 CustomEase、Draggable、ScrollTrigger、SplitText、MorphSVGPlugin 等)。
- Nuxt 4:实现 async lazyLoadPlugin(plugin) 函数——从 pluginMap 取 loader、await 加载模块、取出与 key 同名的导出、gsap.registerPlugin(p),并返回 p;对只在少数组件或单个路由中使用、不广泛使用的插件(如 SplitText、MorphSVG)用懒加载以减小初始包体积。
- Nuxt 4:在组件中通过 const { gsap, ScrollTrigger, lazyLoadPlugin } = useGSAP(); 获取实例与方法,组件内仍使用 gsap.context(scope) 和 onUnmounted → ctx.revert()。
- Svelte:用 bind:this={container} 获取根元素引用,传给 gsap.context(scope),并在 onMount 中创建动画;onMount 中先做 if (!container) return;。
- Svelte:在 onMount 中 return () => ctx.revert(),让清理在组件销毁时自动执行;Svelte 5 生命周期写法不同,但同样遵循「mounted 创建、destroyed 还原」的原则。
- 在影响触发位置的布局变化之后(例如异步数据加载完成)调用 ScrollTrigger.refresh();Vue 中通常在 nextTick 之后、Svelte 中在 tick 之后或异步内容加载完成后调用。
- 不要在组件内直接写不带 scope 的 gsap.to(".box", ...):这种全局选择器可能匹配到其他组件实例或页面其余部分,必须把容器传给 gsap.context() 作第二参数。
适用边界 · 注意事项
- React 项目不适用,应改用 gsap-react(useGSAP hook、gsap.context() 的 React 专用模式)。
- 没有组件生命周期/卸载钩子的环境(例如纯静态脚本、非组件式框架)不需要这套 mounted 创建 + unmount revert 的模式。