transition组件实现过渡效果

要理解过渡(transition)实现的原理,首先需要了解过渡实现的流程,先来看一下图5-1。

image 2024 02 22 20 47 47 702
Figure 1. 图5-1 过渡实现的流程1

当使用 <transition> 组件来包裹 Vue 组件的 template 片段时,这部分内容片段所包括的元素就会形成一个可执行动画组件区域,结合前面的代码,我们来梳理一下实现一个动画的流程:

  • 渐现,就是元素被插入 DOM 并逐渐显示的过程,在插入动画即将开始的一瞬间,<transition> 组件会给其包裹的 <div> 元素两个 class 类,分别是 v-enter-fromv-enter-active,这里的 v 代表在 <transition> 中设置的 name,也就是 fade。这时元素的 opacity(透明度)是 0

  • 当动画的第一帧执行完毕之后,会将 v-enter-from 去除,还保留 v-enter-active,同时新增一个 classv-enter-to,这时 opacity 就会变成初始值 1,CSS 3transition 就会生效,并开始一个过渡动画。

  • 当动画整体执行完成之后,transition 组件会给其包裹的 <div> 元素去除 v-enter-active 这个 class 类,同时也去除 v-enter-to

通过上面的流程,对于每一时刻的 class 状态,可以使用图 5-2 来总结。

image 2024 02 22 21 01 37 803
Figure 2. 图5-2 过渡实现的流程2

利用这个原理,就可以针对每个阶段对应的 class 来设置动画需要的 CSS 样式,以此来实现动画效果。在实现了一个 <div> 元素的 “渐现” 效果之后,接下来将 “渐隐” 效果的实现完善一下,只需要新增两个 CSS 样式即可:

.fade-enter-from {
    opacity: 0
}
.fade-enter-active {
    transition: opacity 2s
}
/*新增两个样式*/
.fade-leave-to {
    opacity: 0
}
.fade-leave-active {
    transition: opacity 2s
}

再次单击切换按钮,就会同时出现 “渐隐” 和 “渐现” 效果。同样,使用一张图来展示 “渐隐” 效果实现的流程,如图 5-3 所示。

image 2024 02 22 21 27 44 665
Figure 3. 图5-3 过渡实现的流程3
  • 渐隐,就是指组件被移除并逐渐消失的过程,在移除动画即将执行的一瞬间,transition 组件会给其包裹的 <div> 元素两个 class 类,分别是 v-leave-fromv-leave-active,这里的 v 代表在 <transition> 中设置的 name,也就是 fade。这时元素的 opacity1(上面渐现时结局的状态)。

  • 当动画的第一帧执行完毕之后,会将 v-leave-from 去除,保留 v-leave-active,同时新增一个 classv-leave-to,这时 opacity 就会套用这个样式,值变成 0CSS 3transition 就会生效,并开始一个过渡动画。

  • 当动画整体执行完成之后,会去除 v-leave-active 这个 class 类,同时也去除 v-leave-to

上面的流程对于每一时刻的 class 状态,可以使用图 5-4 来总结。

image 2024 02 22 21 41 26 326
Figure 4. 图5-4 过渡实现的流程4

上面的代码通过 v-if<transition> 给一个元素添加了 “渐隐渐现” 的过渡效果,实现过渡动画的核心是在元素进入、离开的时刻添加动画逻辑,在这些不同时刻细分了 6 个 class 类,下面来总结一下:

  • v-enter-from:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。

  • v-enter-active:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程、延迟和曲线函数。

  • v-enter-to:定义进入过渡的结束状态。在元素被插入之后的下一帧生效(与此同时 v-enter-from 被移除),在过渡/动画完成之后移除。

  • v-leave-from:定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。

  • v-leave-active:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程、延迟和曲线函数。

  • v-leave-to:定义离开过渡的结束状态。在离开过渡被触发之后的下一帧生效(与此同时 v-leave-from 被删除),在过渡/动画完成之后移除。

另外,在代码中使用的 fade-xxx 是在过渡中切换的类名,类名的定义要遵循一定的规则,如果使用一个没有名字的 <transition>,则 v- 是这些类名的默认前缀,只能使用默认且通用的 v-xxxclass 类。如果给 <transition> 指定了 <transition name="fade">,则 v 可以使用 fade-xxxclass 类,只需要把 v 换成 name 指定的字符串即可,例如 v-enter 会替换为 fade-enter

除了在元素插入/离开时使用 v-if 来增加过渡效果外,也可以在下面的场景中使用 <transition> 组件:

  • 条件显示(使用 v-show)。

  • 动态组件(<route-view>)。

  • 组件根节点。

只要组件所渲染的内容有变化,这些时机都可以添加过渡效果,结合 vue-router<transition> 可以在页面切换时添加我们想要的过渡效果。