You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue2迁移Vue3:外部template控制Transition动画失效求助

Vue3 Transition 过渡动画失效问题解决(Vue2迁移场景)

问题说明

从Vue2迁移至Vue3时,发现相同的Transition写法出现动画失效:在Vue2中,将<transition>放在v-if控制的<template>内部时,显示/隐藏的过渡动画正常工作;但Vue3中该写法无法触发动画。

代码对比

Vue2 可正常工作的代码

<template>
  <div id="app">
    <div id="demo">
      <button v-on:click="show = !show">Toggle</button>

      <template v-if="show">
        <transition name="fade">
          <p>hello</p>
        </transition>
      </template>
    </div>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return { show: true };
  },
};
</script>

<style>
#app {
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.5s;
}
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
  opacity: 0;
}
</style>

Vue3 动画失效的代码

<script>
export default {
  data() {
    return {
      show: true
    }
  }
}
</script>

<template>
  <button @click="show = !show">Toggle</button>
  <template v-if="show">
  <Transition name="fade">
    <p>hello</p>
  </Transition>
  </template>
</template>

<style>
.fade-enter-active,
.fade-leave-active {
  transition: opacity 1.5s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}
</style>

原因分析

Vue3对<Transition>的工作机制做了调整:当v-if控制的是<Transition>组件本身时,隐藏操作会直接销毁整个<Transition>组件,导致组件无法监听内部元素的离开过程,自然无法触发离开动画;而Vue2中允许这种写法是因为内部处理逻辑不同。

解决办法

将v-if移至<Transition>内部的目标元素上,让<Transition>始终存在于DOM中,以完整监听元素的显示/隐藏过渡过程。

修改后的Vue3代码

<script>
export default {
  data() {
    return {
      show: true
    }
  }
}
</script>

<template>
  <button @click="show = !show">Toggle</button>
  <Transition name="fade">
    <p v-if="show">hello</p>
  </Transition>
</template>

<style>
.fade-enter-active,
.fade-leave-active {
  transition: opacity 1.5s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}
</style>

如果需要包裹多个元素,也可以用<template>放在<Transition>内部配合v-if:

<Transition name="fade">
  <template v-if="show">
    <p>hello</p>
    <p>other content</p>
  </template>
</Transition>

内容的提问来源于stack exchange,提问作者Duyo Son

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 04:52:40