自我介绍:大家好,我是吉帅振的网络日志(其他平台账号名字相同),互联网前端开发工程师,工作5年,去过上海和北京,经历创业公司,加入过阿里本地生活团队,现在郑州北游教育从事编程培训。
一、前言
作为一名前端开发工程师,平时开发页面少不了要写一些过渡动画,通常可以用 CSS 脚本来实现,当然一些时候也会使用 JavaScript 操作 DOM 来实现动画。那么,如果我们使用 Vue.js 技术栈,有没有好的实现动画的方式呢?Vue.js 提供了内置的 Transition 组件,它可以让我们轻松实现动画过渡效果。
二、Transition 组件的用法
Transition 组件通常有三类用法:CSS 过渡,CSS 动画和 JavaScript 钩子。我们分别用几个示例来说明:
1.CSS 过渡:
<template>
<div class="app">
<button @click="show = !show">
Toggle render
</button>
<transition name="fade">
<p v-if="show">hello</p>
</transition>
</div>
</template>
<script>
export default {
data() {
return {
show: true
}
}
}
</script>
<style>
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
</style>
CSS 过渡主要定义了一些过渡的 CSS 样式,当我们点击按钮切换文本显隐的时候,就会应用这些 CSS 样式,实现过渡效果。
2.CSS 动画:
<template>
<div class="app">
<button @click="show = !show">Toggle show</button>
<transition name="bounce">
<p v-if="show">Vue is an awesome front-end MVVM framework. We can use it to build multiple apps.</p>
</transition>
</div>
</template>
<script>
export default {
data() {
return {
show: true
}
}
}
</script>
<style>
.bounce-enter-active {
animation: bounce-in 0.5s;
}
.bounce-leave-active {
animation: bounce-in 0.5s reverse;
}
@keyframes bounce-in {
0% {
transform: scale(0);
}
50% {
transform: scale(1.5);
}
100% {
transform: scale(1);
}
}
</style>
和 CSS 过渡类似,CSS 动画主要定义了一些动画的 CSS 样式,当我们去点击按钮切换文本显隐的时候,就会应用这些 CSS 样式,实现动画效果。
3.JavaScript 钩子:
<template>
<div class="app">
<button @click="show = !show">
Toggle render
</button>
<transition
@before-enter="beforeEnter"
@enter="enter"
@before-leave="beforeLeave"
@leave="leave"
css="false"
>
<p v-if="show">hello</p>
</transition>
</div>
</template>
<script>
export default {
data() {
return {
show: true
}
},
methods: {
beforeEnter(el) {
el.style.opacity = 0
el.style.transition = 'opacity 0.5s ease'
},
enter(el) {
this.$el.offsetHeight
el.style.opacity = 1
},
beforeLeave(el) {
el.style.opacity = 1
},
leave(el) {
el.style.transition = 'opacity 0.5s ease'
el.style.opacity = 0
}
}
}
</script>
Transition 组件也允许在一个过渡组件中定义它过渡生命周期的 JavaScript 钩子函数,我们可以在这些钩子函数中编写 JavaScript 操作 DOM 来实现过渡动画效果。
三、Transition 组件的核心思想
通过前面三个示例,我们不难发现都是在点击按钮时,通过修改 v-if 的条件值来触发过渡动画的。其实 Transition 组件过渡动画的触发条件有以下四点:条件渲染 (使用 v-if);条件展示 (使用 v-show);动态组件;组件根节点。所以你只能在上述四种情况中使用 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 被删除),在过渡动画完成之后移除。
其实说白了 Transition 组件的核心思想就是,Transition 包裹的元素插入删除时,在适当的时机插入这些 CSS 样式,而这些 CSS 的实现则决定了元素的过渡动画。
四、Transition 组件的实现原理
<template>
<div class="app">
<button @click="show = !show">
Toggle render
</button>
<transition name="fade">
<p v-if="show">hello</p>
</transition>
</div>
</template>
模板编译后生成的 render 函数:
import { createVNode as _createVNode, openBlock as _openBlock, createBlock as _createBlock, createCommentVNode as _createCommentVNode, Transition as _Transition, withCtx as _withCtx } from "vue"
export function render(_ctx, _cache, $props, $setup, $data, $options) {
return (_openBlock()