不能直接用transition切换两个组件,必须通过状态驱动同一容器内组件的显隐;推荐opacity+transform组合动画,配合统一容器、唯一key、unmountOnExit等配置确保过渡连贯。

用 transition 直接切两个组件?不行,得靠状态驱动
CSS 的 transition 只对「同一元素的属性变化」生效,不能跨 DOM 节点触发。两个完全独立的组件(比如 Home 和 About)切换时,旧组件卸载、新组件挂载,DOM 节点本身都换了,transition 没东西可过渡。
真正能动的是「包裹它们的容器」或「组件内部的根元素」——前提是它们得同时存在、只是显隐切换。
- 推荐做法:用一个统一容器控制显示逻辑,让两个组件始终在 DOM 中(比如用
display: none或opacity: 0+visibility: hidden控制),再配合transition动画属性 - React/Vue 场景下,别依赖
key强制重渲染,否则动画会断;要用className或v-bind:class切换状态类名 - 注意:
display: none会彻底移除渲染流,无法过渡;必须用opacity、transform、height(配合overflow: hidden)等可动画属性
opacity + transform 是最稳的组合
这两个属性浏览器优化好、硬件加速支持广、兼容性也强(IE10+)。单靠 opacity 会留白占位,单靠 transform(比如 translateX)可能影响点击区域,合起来用才能既平滑又干净。
- 典型写法:
.fade-enter { opacity: 0; transform: translateX(20px); }+.fade-enter-active { transition: opacity 0.3s ease, transform 0.3s ease; } - 进入和离开动画要成对设计,比如
fade-enter/fade-enter-active和fade-leave/fade-leave-active,否则新旧组件会“叠在一起闪一下” - Vue 的
<transition>或 React 的CSSTransition库默认只加-enter类,离开类需手动补全,否则离开没动画
React 中用 CSSTransition 容易漏掉 unmountOnExit
默认情况下,CSSTransition 动画结束后 DOM 节点还在,只是加了 exit 类。如果组件里有定时器、请求或 useEffect 清理逻辑,不及时卸载会导致内存泄漏或重复执行。
立即学习“前端免费学习笔记(深入)”;
- 务必设
unmountOnExit={true},确保动画结束立刻从 DOM 移除节点 - 但要注意:如果这个组件里有表单输入,且你希望保留用户输入内容(比如多步表单),就不能用
unmountOnExit,得改用in属性控制显隐 + 手动管理状态 -
timeout值必须和 CSS 中transition-duration严格一致,否则 React 会提前移除类名,动画截断
Vue 的 <transition> 需手动处理 key 冲突
当两个组件是同级、且用同一个 v-if 控制时,Vue 默认复用元素(因为 key 相同),导致过渡类名不触发。这是最常被忽略的坑。
- 解决方案:给每个组件加唯一
key,比如<Home key="home" v-if="view === 'home'" />和<About key="about" v-if="view === 'about'" /> - 别用
:key="view"这种动态值——看似简洁,但若view是字符串且没变,key 就不变,复用逻辑照旧生效 - 如果用了
<keep-alive>,过渡会失效(因为组件没销毁),此时得用include+ 手动控制activated/deactivated钩子做入场逻辑


















