Vue 3动画效果实现:transition和transition-group深入剖析

2025-04发布7次浏览

Vue 3 中的 transitiontransition-group 是实现动画效果的核心工具。通过这两个组件,开发者可以轻松地为 DOM 元素和列表添加进入、离开以及切换时的过渡效果。本文将深入剖析 transitiontransition-group 的工作原理,并结合实际案例展示如何使用它们来创建优雅的动画。


一、transition 的基本概念与用法

transition 是 Vue 提供的一个内置组件,用于在元素插入、更新或移除时应用 CSS 动画或过渡效果。

1. 基本结构

<transition name="fade">
  <p v-if="show">Hello, Vue 3!</p>
</transition>

在上面的例子中,当 show 的值发生变化时,<p> 元素会被动态地插入或移除,同时触发相应的过渡效果。

2. 过渡类名

Vue 会自动为 transition 组件中的元素添加以下类名:

  • 进入类名v-enter-from(初始状态)、v-enter-active(过渡过程)、v-enter-to(最终状态)
  • 离开类名v-leave-from(初始状态)、v-leave-active(过渡过程)、v-leave-to(最终状态)

如果设置了 name="fade",则类名前缀会变为 fade-

3. 示例代码

以下是一个简单的淡入淡出效果的实现:

.fade-enter-from, .fade-leave-to {
  opacity: 0;
}
.fade-enter-active, .fade-leave-active {
  transition: opacity 0.5s ease;
}

结合上述 HTML 结构,当 showfalse 变为 true 时,文本会淡入;反之则淡出。


二、transition-group 的基本概念与用法

transition-grouptransition 的扩展版本,专门用于处理列表项的动画效果。它允许对列表中的每个元素分别应用进入、离开和移动的动画。

1. 基本结构

<transition-group name="list" tag="ul">
  <li v-for="(item, index) in items" :key="item.id">{{ item.name }}</li>
</transition-group>

在上面的例子中,tag 属性指定了渲染的根标签类型(如 uldiv),而 v-for 用于生成列表项。

2. 过渡类名

transition-group 的过渡类名与 transition 类似,但还支持额外的移动动画类名:

  • 进入类名list-enter-fromlist-enter-activelist-enter-to
  • 离开类名list-leave-fromlist-leave-activelist-leave-to
  • 移动类名list-move

3. 示例代码

以下是一个列表项上下滑动的动画效果:

.list-enter-active, .list-leave-active {
  transition: all 0.5s ease;
}
.list-enter-from, .list-leave-to {
  opacity: 0;
  transform: translateY(30px);
}
.list-move {
  transition: transform 0.5s ease;
}

结合上述 HTML 结构,当列表项新增或移除时,会触发上下滑动的动画;当列表项重新排序时,会触发平滑的移动动画。


三、高级用法与技巧

1. 使用 JavaScript 钩子函数

除了 CSS 动画,还可以通过 JavaScript 钩子函数来控制更复杂的动画逻辑。例如:

<transition
  @before-enter="beforeEnter"
  @enter="enter"
  @after-enter="afterEnter"
  @leave="leave"
>
  <p v-if="show">Hello, Vue 3!</p>
</transition>

钩子函数示例:

export default {
  methods: {
    beforeEnter(el) {
      el.style.opacity = 0;
    },
    enter(el, done) {
      let height = 0;
      const interval = setInterval(() => {
        height += 5;
        el.style.height = `${height}px`;
        el.style.opacity = height / 100;

        if (height >= 100) {
          clearInterval(interval);
          done();
        }
      }, 20);
    },
    afterEnter(el) {
      console.log('动画完成');
    },
    leave(el, done) {
      el.style.opacity = 1;
      let height = 100;
      const interval = setInterval(() => {
        height -= 5;
        el.style.height = `${height}px`;
        el.style.opacity = height / 100;

        if (height <= 0) {
          clearInterval(interval);
          done();
        }
      }, 20);
    }
  }
};

2. 自定义过渡模式

transition 支持自定义过渡模式,包括 in-outout-in

  • in-out:新元素先进入,完成后旧元素再离开。
  • out-in:旧元素先离开,完成后新元素再进入。

示例:

<transition name="fade" mode="out-in">
  <component :is="currentView"></component>
</transition>

四、动画流程图

以下是 transitiontransition-group 的动画生命周期流程图:

stateDiagram-v2
    [*] --> BeforeEnter
    BeforeEnter --> Enter
    Enter --> AfterEnter
    AfterEnter --> [*]

    state Enter {
        [*] --> ActiveTransition
        ActiveTransition --> ToState
        ToState --> [*]
    }

    [*] --> BeforeLeave
    BeforeLeave --> Leave
    Leave --> AfterLeave
    AfterLeave --> [*]

    state Leave {
        [*] --> ActiveTransition
        ActiveTransition --> ToState
        ToState --> [*]
    }

五、总结

通过 transitiontransition-group,Vue 3 提供了灵活且强大的动画解决方案。无论是简单的淡入淡出效果,还是复杂的列表项动画,都可以通过 CSS 或 JavaScript 轻松实现。掌握这些工具后,开发者可以为用户提供更加流畅和直观的交互体验。