从一个简单的动画开始

对于前端动画而言,动画出现的时机大多数出现在对 DOM 节点的插入、更新或者删除过程中。在 Vue 项目中,在插入、更新或者删除 DOM 时,可以使用多种不同方式来实现动画或者过渡效果,包括以下方式:

  • CSS 过渡和动画中自动应用 class

  • 可以配合使用第三方 CSS 动画库,如 Animate.css

  • 在过渡钩子函数中使用 JavaScript 直接操作 DOM

  • 可以配合使用第三方 JavaScript 动画库,如 Velocity.js

Vue 项目中实现动画时,首先需要明白一点,作为一个前端项目来说,使用原生的 CSS 3 动画,例如 transition(过渡)、animation(动画)来实现各种动画效果是完全可以的。同理,直接采用 JavaScript 来操作 DOM 实现动画也没问题,包括使用一些第三方的动画库。但是,针对动画本身,Vue 提供了一些新的 API,它能够结合传统的 CSS 3 动画,并搭配一些 Vue 内置组件和指令,来帮助开发者简化动画的开发流程,更加便捷地开发出高质量的动画效果。

下面先来看一个简单的 Vue 动画案例,如示例代码 5-1-1 所示。

示例代码 5-1-1 一个简单的 Vue 动画
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>vue动画</title>
    <script src="https://unpkg.com/vue@3.2.28/dist/vue.global.js"></script>
</head>
<body>
<div id="app">
    <button @click="clickCallback">切换</button>
    <div id="box" v-if="show">Hello!</div>
</div>
<script type="text/javascript">
    Vue.createApp({
        data() {
            return {show: true}
        },
        methods:{
            clickCallback(){
                this.show = !this.show
            }
        }
    }).mount("#app")
</script>
</body>
</html>

上面的代码是完整的 HTML 代码,可以直接在浏览器上运行,本章也会以这段代码为基础来进行讲解。

上面的代码含有一个简单的逻辑,通过单击切换按钮来控制 id#box 这个 <div> 的显示和隐藏,其中使用了 v-if 指令来进行控制。在体验这段代码的交互操作时,<div> 的显示和隐藏比较突兀,因此添加了一个 “渐隐渐现” 的过渡效果,以提升用户的体验,这个过渡效果的实现使用了 Vue 的内置动画组件 transition,如示例代码 5-1-2 所示。

示例代码 5-1-2 transition 动画组件的运用
<div id="app">
    <button @click="clickCallback">切换</button>
    <transition name="fade">
        <div v-if="show">Hello!</div>
    </transition>
</div>

<transition> 组件对 <div> 元素进行包裹,同时设置 name 属性为 fade,即表示对包裹的这个 div 采用 fade 这个动画效果。当然,fade 动画效果需要使用 CSS 3 来实现。继续看下面的代码,在 style 中添加样式,如示例代码 5-1-3 所示。

示例代码 5-1-3 transition 和 CSS 3 过渡
<style type="text/css">
    .fade-enter-from {
        opacity: 0
    }
    .fade-enter-active {
        transition: opacity 2s
    }
</style>

在这段代码中设置了两个 CSS 样式,分别以 fade- 开头设置透明度 opacity 属性的 CSS 3 过渡效果。这时再次单击切换按钮时,会发现 Hello 出现的过程中有一个过渡的 “渐现” 效果。

Vue 中的动画效果主要分为两类,一类是 transition,另一类是 animation。上面的示例实现了简单的过渡效果,接下来具体讲解一下 <transition> 是如何实现这两种效果的。