transition组件通过4个核心js钩子(before-enter、enter、after-enter、before-leave)实现精细动画控制,需在methods中定义并传入,注意调用done()、避免箭头函数、协调css与js动画冲突。

Options API 中的 Transition 组件通过 JavaScript 钩子函数,可以在动画不同阶段执行自定义逻辑,实现比 CSS 更精细的控制(比如动态计算样式、监听第三方库动画、触发数据更新、或与 Canvas/WebGL 同步)。关键在于正确挂载钩子并配合 v-if 或 v-show 触发过渡流程。
必须掌握的 4 个 JS 钩子时机
Transition 组件支持以下六个钩子(其中 before-leave 和 leave-cancelled 常被忽略但很实用):
- before-enter:元素插入 DOM 前调用,此时元素尚未渲染,适合初始化状态(如设置初始 transform、opacity)
- enter:元素已插入、CSS 动画/transition 尚未开始,适合手动触发动画(如 requestAnimationFrame 启动 JS 动画)
- after-enter:CSS 动画/transition 完成后调用,适合清理、标记完成状态、或触发后续逻辑
- enter-cancelled:enter 过程中被中断(如快速切换显隐)时调用,必须重置元素状态,否则下次 enter 可能异常
- before-leave:元素即将离开前调用,适合保存当前尺寸、滚动位置或触发退出前的数据校验
-
leave-cancelled:leave 被中断时调用,需恢复元素可见性及内联样式(尤其当用了
display: none)
钩子函数如何绑定到组件实例
在 Options API 的 methods 中定义钩子函数,再通过 <transition></transition> 的属性传入。注意:钩子接收原生 DOM 元素作为唯一参数,不是 Vue 实例。
export default {
methods: {
beforeEnter(el) {
el.style.opacity = 0
el.style.transform = 'translateY(20px)'
},
enter(el, done) {
// 使用 JS 动画(如 GSAP、anime.js)或 requestAnimationFrame
const anim = anime({
targets: el,
opacity: [0, 1],
translateY: [20, 0],
duration: 300,
easing: 'ease-out',
complete: done // 必须调用 done() 告诉 Vue 动画结束
})
},
afterEnter(el) {
console.log('动画完成,可触发事件或更新 state')
this.isAnimating = false
},
beforeLeave(el) {
// 记录当前高度,用于 height 过渡
el._originalHeight = el.offsetHeight
},
leave(el, done) {
// 手动控制高度收缩(避免 CSS height: auto 无法过渡)
const height = el.offsetHeight
el.style.height = height + 'px'
// 强制重排,确保 height 生效
getComputedStyle(el).height
el.style.height = '0'
el.style.overflow = 'hidden'
// 监听 transitionend 或用 setTimeout 模拟
el.addEventListener('transitionend', () => {
el.style.overflow = ''
done()
}, { once: true })
}
}
}
常见陷阱与避坑建议
-
忘记调用
done():使用enter或leave时若启用appear或异步逻辑,未调用done()会导致 Vue 卡住过渡状态,元素无法进入/离开 -
钩子内访问
this失效:钩子是普通函数,this指向 Vue 实例——但仅在方法定义在methods中且未被箭头函数包裹时才成立;避免在钩子内部直接写箭头函数 -
多个过渡嵌套时钩子触发顺序混乱:外层 Transition 的
after-enter可能早于内层的enter,需用事件总线或$nextTick协调 -
CSS 与 JS 动画冲突:若同时声明了
enter-active-class和enter钩子,CSS transition 会与 JS 动画竞争,建议禁用 CSS 动画:enter-active-class="!transition-none"(配合 Tailwind)或移除相关 class
配合 v-show / v-if 的行为差异
v-if 触发完整生命周期:before-enter → enter → after-enter(显示),before-leave → leave → after-leave(隐藏);v-show 只触发 enter 和 leave(因为 DOM 一直存在),且不会调用 before-enter/before-leave —— 若需初始化样式,应在 enter 中判断 el.style.opacity === '' 并补全。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











