transition组件实现过渡效果
要理解过渡(transition)实现的原理,首先需要了解过渡实现的流程,先来看一下图5-1。
当使用 <transition> 组件来包裹 Vue 组件的 template 片段时,这部分内容片段所包括的元素就会形成一个可执行动画组件区域,结合前面的代码,我们来梳理一下实现一个动画的流程:
-
渐现,就是元素被插入
DOM并逐渐显示的过程,在插入动画即将开始的一瞬间,<transition>组件会给其包裹的<div>元素两个class类,分别是v-enter-from和v-enter-active,这里的v代表在<transition>中设置的name,也就是fade。这时元素的opacity(透明度)是0。 -
当动画的第一帧执行完毕之后,会将
v-enter-from去除,还保留v-enter-active,同时新增一个class类v-enter-to,这时opacity就会变成初始值 1,CSS 3的transition就会生效,并开始一个过渡动画。 -
当动画整体执行完成之后,
transition组件会给其包裹的<div>元素去除v-enter-active这个class类,同时也去除v-enter-to。
通过上面的流程,对于每一时刻的 class 状态,可以使用图 5-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 所示。
-
渐隐,就是指组件被移除并逐渐消失的过程,在移除动画即将执行的一瞬间,
transition组件会给其包裹的<div>元素两个class类,分别是v-leave-from和v-leave-active,这里的v代表在<transition>中设置的name,也就是fade。这时元素的opacity为1(上面渐现时结局的状态)。 -
当动画的第一帧执行完毕之后,会将
v-leave-from去除,保留v-leave-active,同时新增一个class类v-leave-to,这时opacity就会套用这个样式,值变成0,CSS 3的transition就会生效,并开始一个过渡动画。 -
当动画整体执行完成之后,会去除
v-leave-active这个class类,同时也去除v-leave-to。
上面的流程对于每一时刻的 class 状态,可以使用图 5-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-xxx 的 class 类。如果给 <transition> 指定了 <transition name="fade">,则 v 可以使用 fade-xxx 的 class 类,只需要把 v 换成 name 指定的字符串即可,例如 v-enter 会替换为 fade-enter。
除了在元素插入/离开时使用 v-if 来增加过渡效果外,也可以在下面的场景中使用 <transition> 组件:
-
条件显示(使用
v-show)。 -
动态组件(
<route-view>)。 -
组件根节点。
只要组件所渲染的内容有变化,这些时机都可以添加过渡效果,结合 vue-router 和 <transition> 可以在页面切换时添加我们想要的过渡效果。