transition类无法实现真正页面切换动画,因其仅响应元素自身属性渐变,而路由跳转是dom整体替换,需js控制class切换配合transform/opacity等可过渡属性,并用document.startviewtransition解耦更新与动画。

直接用 transition 类无法实现真正的页面切换动画——它只响应元素自身属性的渐变变化,而路由跳转是 DOM 的整体替换或重渲染,transition 本身不感知“页面卸载”或“新页面挂载”这类事件。
为什么 transition-all + duration-300 不动?
常见错误是给 <outlet></outlet> 或路由容器加 transition-all duration-300,却没配状态切换逻辑。CSS 的 transition 不会自动监听 React Router 的 location 变化,也不会在组件 unmount 时保留动画帧。
-
transition必须作用于「正在被修改样式」的元素上,且该元素需始终在 DOM 中(不能靠v-if或key强制销毁重建) - 只写
transition不指定duration和timing-function,浏览器按默认0s处理,等于没动 - 若目标元素初始状态和结束状态之间没有可插值属性(比如从
display: none切到block),动画直接跳变
必须配合 JS 控制的 class 切换
真正可行的做法是:用 JS 主动添加/移除进入/离开类,并确保过渡属性写在基础样式里,而非伪类或临时声明中。
- 进入动画类示例:
page-enter→page-enter-active(含opacity-0 translate-x-full到opacity-100 translate-x-0) - 离开动画类示例:
page-leave→page-leave-active(反向,且需pointer-events-none防止中途点击干扰) - 基础样式必须提前定义:
.page-enter-active, .page-leave-active { transition: opacity 0.4s, transform 0.4s; } - 离开动画要靠
useLayoutEffect在 DOM 卸载前捕获并应用类,否则unmount太快,动画根本来不及播
别碰 display、height、top 这些属性
它们要么不可过渡(display),要么触发重排(height、top),导致卡顿甚至动画撕裂。
- 位移统一用
transform: translateX(),不是left或margin-left - 显隐用
opacity+visibility: hidden组合,不用display: none - 容器必须设
overflow-hidden,否则translateX滑出时内容溢出可见 - 父级需有明确
position: relative或absolute,否则transform基准错乱
更推荐用 document.startViewTransition()
这是目前唯一能真正解耦“DOM 更新”和“动画控制”的原生方案,transition 只适合局部组件动画,页面级切换硬套它容易陷入 class 管理混乱、状态不同步、快速连点失效等问题。
- 必须把 DOM 更新逻辑包进
document.startViewTransition(() => { ... })回调里,且同步执行 - 不能先改 state 再等 React 渲染完成——那样会抛
InvalidStateError - CSS 中用
::view-transition-old(root)和::view-transition-new(root)定义动画,浏览器自动捕获前后快照 - 当前支持 Chrome 111+、Edge 111+、Firefox 117+(Safari 尚未支持),生产环境需降级 fallback
真正麻烦的不是写几行 transition,而是处理路由切换时旧页面卸载时机、新页面挂载节奏、以及快速导航下的 class 冲突——这些都得靠 JS 精确控制,CSS 本身只负责描述“怎么动”,不负责“什么时候动”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











