目录
组件
基于CSS的过渡效果
JavaScript钩子
Vue 提供了两个内置组件,可以帮助你制作基于状态变化的过渡和动画:
-
<Transition>
会在一个元素或组件进入和离开 DOM 时应用动画。 -
<TransitionGroup>
会在一个v-for
列表中的元素或组件被插入,移动,或移除时应用动画。
除了这两个组件,我们也可以通过其他技术手段来应用动画,比如切换 CSS class 或用状态绑定样式来驱动动画。
<Transition>组件
<Transition>是一个内置组件,这意味着它在任意别的组件中都可以被使用,无需注册。它可以将进入和离开动画应用到通过默认插槽传递给它的元素或组件上。进入或离开可以由以下的条件之一触发:
- 由 v-if 所触发的切换
- 由 v-show 所触发的切换
- 由特殊元素 <component> 切换的动态组件
- 改变特殊的 key 属性
以下是基本用法示例:
<button @click="show = !show">Toggle</button>
<Transition>
<p v-if="show">hello</p>
</Transition>
/* 下面我们会解释这些 class 是做什么的 */
.v-enter-active,
.v-leave-active {
transition: opacity 0.5s ease;
}
.v-enter-from,
.v-leave-to {
opacity: 0;
}
当一个 <Transition>
组件中的元素被插入或移除时,会发生下面这些事情:
-
Vue 会自动检测目标元素是否应用了 CSS 过渡或动画。如果是,则一些 CSS 过渡 class 会在适当的时机被添加和移除。
-
如果有作为监听器的 JavaScript 钩子,这些钩子函数会在适当时机被调用。
-
如果没有探测到 CSS 过渡或动画、也没有提供 JavaScript 钩子,那么 DOM 的插入、删除操作将在浏览器的下一个动画帧后执行。
基于CSS的过渡效果
CSS过渡class
一共有6个应用于进入与离开过渡效果的CSS class。
-
v-enter-from
:进入动画的起始状态。在元素插入之前添加,在元素插入完成后的下一帧移除。 -
v-enter-active
:进入动画的生效状态。应用于整个进入动画阶段。在元素被插入之前添加,在过渡或动画完成之后移除。这个 class 可以被用来定义进入动画的持续时间、延迟与速度曲线类型。 -
v-enter-to
:进入动画的结束状态。在元素插入完成后的下一帧被添加 (也就是v-enter-from
被移除的同时),在过渡或动画完成之后移除。 -
v-leave-from
:离开动画的起始状态。在离开过渡效果被触发时立即添加,在一帧后被移除。 -
v-leave-active
:离开动画的生效状态。应用于整个离开动画阶段。在离开过渡效果被触发时立即添加,在过渡或动画完成之后移除。这个 class 可以被用来定义离开动画的持续时间、延迟与速度曲线类型。 -
v-leave-to
:离开动画的结束状态。在一个离开动画被触发后的下一帧被添加 (也就是v-leave-from
被移除的同时),在过渡或动画完成之后移除。
v-enter-active
和 v-leave-active
给我们提供了为进入和离开动画指定不同速度曲线的能力,我们将在下面的小节中看到一个示例。
为过渡效果命名
我们可以给<Transition>组件传入一个 name prop来声明一个过渡效果名:
<Transition name="fade">
...
</Transition>
对于一个有名字的过渡效果,对它起作用的过渡class 会以其名字而不是 v 作为前缀。比如,上方例子中被应用的class将会是 fade-enter-active 而不是 v-enter-active。这个“fade"过渡的class应该是这样:
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
CSS的transition
<Transition> 一般都会搭配原生CSS过渡一起使用,正如你在上面的例子中所看到的那样。这个transition CSS属性是一个简写形式,使我们可以一次定义一个过渡的各个方面,包括需要执行动画的属性、持续时间和速度曲线。
下面是一个更高级的例子,它使用了不同的持续时间和速度曲线来过渡多个属性:
<Transition name="slide-fade">
<p v-if="show">hello</p>
</Transition>
/*
进入和离开动画可以使用不同
持续时间和速度曲线。
*/
.slide-fade-enter-active {
transition: all 0.3s ease-out;
}
.slide-fade-leave-active {
transition: all 0.8s cubic-bezier(1, 0.5, 0.8, 1);
}
.slide-fade-enter-from,
.slide-fade-leave-to {
transform: translateX(20px);
opacity: 0;
}
JavaScript钩子
你可以通过监听 <Transition> 组件事件的方式在过渡过程中挂上钩子函数:
<Transition
@before-enter="onBeforeEnter"
@enter="onEnter"
@after-enter="onAfterEnter"
@enter-cancelled="onEnterCancelled"
@before-leave="onBeforeLeave"
@leave="onLeave"
@after-leave="onAfterLeave"
@leave-cancelled="onLeaveCancelled"
>
<!-- ... -->
</Transition>
// 在元素被插入到 DOM 之前被调用
// 用这个来设置元素的 "enter-from" 状态
function onBeforeEnter(el) {}
// 在元素被插入到 DOM 之后的下一帧被调用
// 用这个来开始进入动画
function onEnter(el, done) {
// 调用回调函数 done 表示过渡结束
// 如果与 CSS 结合使用,则这个回调是可选参数
done()
}
// 当进入过渡完成时调用。
function onAfterEnter(el) {}
function onEnterCancelled(el) {}
// 在 leave 钩子之前调用
// 大多数时候,你应该只会用到 leave 钩子
function onBeforeLeave(el) {}
// 在离开过渡开始时调用
// 用这个来开始离开动画
function onLeave(el, done) {
// 调用回调函数 done 表示过渡结束
// 如果与 CSS 结合使用,则这个回调是可选参数
done()
}
// 在离开过渡完成、
// 且元素已从 DOM 中移除时调用
function onAfterLeave(el) {}
// 仅在 v-show 过渡中可用
function onLeaveCancelled(el) {}
这些钩子可以与CSS过渡或动画结合使用,也可以单独使用。
在使用仅由JS执行的动画时,最好是添加一个 :css="false" prop。这显式地向Vue表明可以路过对CSS过渡的自动探测。除了性能稍好一些之外,还可以防止CSS规则意外地干扰过渡效果。
<Transition
...
:css="false"
>
...
</Transition>
在有了 :css="false" 后,我们就自己全权负责控制什么时候过渡结束了。这种情况下对于@enter和@leave钩子来说,回调函数done就是必须的。否则,钩子将被同步调用,过渡将立即完成。