likes
comments
collection
share

(22)Vue 中的动画特效——① Vue 中的 CSS 动画原理 | Vue 基础理论实操

作者站长头像
站长
· 阅读数 40
本文版权归 “公众号 | 前端一万小时” 所有,欢迎转载!

转载请注明出处,未经同意,不可修改文章内容。

🔥🔥🔥本系列文章已在“公众号 | 前端一万小时”更新完毕,有需要的小伙伴可按需前往查看。

🔥🔥🔥“前端一万小时”两大明星专栏——“从零基础到轻松就业”、“前端面试刷题”,已于本月大改版,合二为一,干货满满,欢迎点击公众号菜单栏各模块了解。


1 “按钮”控制页面展示与否

在讲解动画原理之前,我们先来实现一个非常简单的功能。通过点击“切换”按钮来控制页面内容展示与否。

代码及功能效果如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>前端一万小时-Vue 中 CSS 动画原理</title>
  <script src="./vue.js"></script>
</head>
<body>
  <div id="root">
    <div v-if="show">Hello,前端一万小时</div> <!-- 1️⃣在组件中创建一个 div 标签,
    																				内容是“Hello,前端一万小时”;
    																				2️⃣内容的显示与否,通过 v-if 的 show 来决定;
    																				-->
    
    <button @click="handleClick">切换</button> <!-- 4️⃣增加一个 button “切换”按钮,
    																					并绑定 click 事件 handleClick; -->
  </div>

  <script>
    var vm = new Vue({
      el: "#root",
      data: {
        
        show: true // 3️⃣在 data 中定义 show,默认值为 true;
        
      },
      
      methods: {
        handleClick: function() { // 5️⃣在 methods 中写 handleClick 的逻辑。
          this.show = !this.show  
        }
      }
    })
  </script>
</body>
</html>

(22)Vue 中的动画特效——① Vue 中的 CSS 动画原理 | Vue 基础理论实操

2 页面效果渐隐渐现(动画)的效果

现在有一个需求:让 Hello,前端一万小时 在显示/隐藏时,有渐隐渐现的动画效果。

如果希望 Hello,前端一万小时 有动画效果的话,那么在它的标签外层,要用一个 <transition> 标签把它包裹起来:

<div id="root">
  
  <transition name="fade"> <!-- 🚀给 transition 起名叫 fade(或者其他任意名字都可以)。 -->
    <div v-if="show">Hello,前端一万小时</div>
  </transition>
  
  <button @click="handleClick">切换</button>
</div>

当写完这些代码后,再到页面上刷新查看:

(22)Vue 中的动画特效——① Vue 中的 CSS 动画原理 | Vue 基础理论实操

发现动画效果并没有出现!这是什么原因呢?其实我们的代码并没有写完。

2.1 过渡动画的原理

在写下一部分代码之前,我们先把 transition 对应的过渡动画的原理搞清楚。 (22)Vue 中的动画特效——① Vue 中的 CSS 动画原理 | Vue 基础理论实操 当一个元素被 transition 包裹了之后,Vue 会自动分析元素的 CSS 样式,然后构建一个动画的流程。

上图的黑线条及线条上的三个圆就是动画的流程:

  1. 在动画即将被执行的这个瞬间(动画即将开始时),Vue 会给被 transition 包裹的 div 上增加两个 class 名,分别是 fade-enter 和 fade-enter-active。

  2. 当动画第一帧执行结束后(动画过程中),Vue 分析了 transition 标签、知道它是一个动画效果后,在动画运行到第二帧时会把 fade-enter 的 class 去除,同时再增加一个 fade-enter-to 的 class 名。

  3. 接着动画执行到结束时,Vue 会把 fade-enter-active 和 fade-enter-to 这两个 class 移除。

我们继续看下文的代码实例。

2.2 显示的动画

当一个 div 元素被 <transition> 包裹起来时,Vue 会自动构建一个动画流程。

我们给在动画即将开始时添加的 fade-enter 和 fade-enter-active 两个 class 写一些样式:

<head>
  <meta charset="UTF-8">
  <title>前端一万小时-Vue 中 CSS 动画原理</title>
  <script src="./vue.js"></script>
  <style>
    
    .fade-enter {
      opacity: 0;
    } /* 🚀在第一帧的时候 .fade-enter 的样式会被增加进来。 */

    .fade-enter-active {
      transition: opacity 3s;
    }
  </style>
</head>

保存后在浏览器中打开点击“切换”,隐藏了 Hello,前端一万小时 后,再显示的时候,有一个明显的过渡效果:

(22)Vue 中的动画特效——① Vue 中的 CSS 动画原理 | Vue 基础理论实操

❓为什么这样写就有动画效果呢?(22)Vue 中的动画特效——① Vue 中的 CSS 动画原理 | Vue 基础理论实操 如上图所示, .fade-enter-active 在动画即将开始时就已经存在了,而直到动画结束时才被移除。而我们在这个 class 里写的内容就是对 opacity 进行一个 transition 的监控。如果监控到 opacity 发生变化,就会让元素的不透明度在 3 秒之间,慢慢的渐变到 opacity 对应的值。

接下来继续看 fade-enter:

fade-enter 在第一帧的时候存在,但当动画运行到第二帧的时候它就被移除了。我们在 .fade-enter 里面写了 opacity: 0;。当点击按钮时,页面即将被显示(动画运行到第一帧),fade-enter 和 fade-enter-active 一起存在。这时,这个 div 标签是处于隐藏状态。

当动画运行到第二帧,Vue 自动移除了 fade-enter,然后 div 元素上的 opacity 就自动恢复到了原始的值 1。恰好 fade-enter-active 监听到 opacity 发生了变化,那么它会让这个变化在 3 秒钟内完成。这样就使得我们慢慢显示的动画效果得以实现!

❓为什么 class 名都以 fade 开头?

答:因为我们给 transition 起的名字叫“fade”,所以 class 名都是用 fade 开头。如果不给 transition 起名,那么 Vue 默认的前缀是 v ,即 v-enter / v-enter-active 等。

所以代码这样写也是可以的:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>前端一万小时-Vue 中 CSS 动画原理</title>
  <script src="./vue.js"></script>
  
  <style> /* ❗️fade 替换成了 v。 */
    .v-enter {
      opacity: 0;
    }

    .v-enter-active {
      transition: opacity 3s;
    }
  </style>
  
</head>
<body>
  <div id="root">
    <transition>
      <div v-if="show">Hello,前端一万小时</div>
    </transition>
    <button @click="handleClick">切换</button>
  </div>

  <script>
    var vm = new Vue({
      el: "#root",
      data: {
        show: true
      },
      methods: {
        handleClick: function() {
          this.show = !this.show
        }
      }
    })
  </script>
</body>
</html>

2.3 隐藏的动画

(22)Vue 中的动画特效——① Vue 中的 CSS 动画原理 | Vue 基础理论实操 当一个 div 元素被包裹在 transition 标签之内时,这个 div 元素从“显示”状态变为“隐藏”状态的动画效果流程如上图。

这时 Vue 会自动构建一个隐藏的动画流程:

  1. 隐藏的第一个瞬间时,Vue 会自动增加 fade-leave 和 fade-leave-active 的 class;
  2. 在第二帧时,Vue 会把 fade-leave 去除掉,增加一个 fade-leave-to 的 class;
  3. 最后一帧时,Vue 会把 fade-leave-active 和 fade-leave-to 这两个 class 都移除。

结合这些 Vue 会自动做的事,我们就可以编写出当元素隐藏状态的动画效果了:

  <style>
    .v-enter {
      opacity: 0;
    }

    .v-enter-active {
      transition: opacity 3s;
    }

    /* ❗️隐藏状态的动画 CSS 代码。 */
    .v-leave-to {
      opacity: 0;
    }

    .v-leave-active {
      transition: opacity 3s;
    }
  </style>

保存后,刷新页面可以看到,隐藏/显示时都有动画效果:

(22)Vue 中的动画特效——① Vue 中的 CSS 动画原理 | Vue 基础理论实操

❓为什么加了这段代码,就有隐藏状态的动画效果了? (22)Vue 中的动画特效——① Vue 中的 CSS 动画原理 | Vue 基础理论实操 答:先看 v-leave-active,也就是上图中的 fade-leave-active:从动画执行的第一个瞬间,到动画执行完毕,整个过程中 fade-leave-active 都存在。即在动画运行过程中,我们要求时刻监听 div 的 opacity 属性,一旦 opacity 属性发生变化,就让它在 3 秒慢慢的进行过渡。

再看 v-leave-to,即图中的 fade-leave-to:在离开动画执行的第一个瞬间,并没有执行 fade-leave-to 的一些操作,而是在第二个瞬间才把 fade-leave-to 加上。

❓在第一个瞬间,div 标签的 opacity 是多少?

答:当从显示状态变成隐藏状态时,第一个瞬间还是显示的,即 opacity 还是 1。

动画到第二帧时,把 fade-leave-to 加进来了,opacity 突然就变成 0 了。恰好我们一直让 fade-leave-acitve 监听着 div 的 opacity 变化,所以当 opacity 从 1 变为 0 时,这个变化就有 3 秒的过渡。同时 fade-leave-to 一直存在,直到动画结束后才会被取消掉。

通过这种在某一时刻,自动向 div 元素上增加一些 class 的底层原理,Vue 帮我们实现了 CSS 动画效果。因为这种动画是通过 CSS3 里的 transition 来实现的,transition 翻译成中文就是“过渡”,所以 Vue 也把这种动画效果叫做“过渡动画”效果。

❓div 的显示和隐藏是通过 v-if 来控制的,改成 v-show 可不可以?

答:可以。只要用 transition 标签包裹在 div 的外层,不管是用 v-if 还是 v-show 来控制显示或隐藏,都会带有动画效果。(除了 v-show 和 v-if 之外,甚至写动态组件也会自带过渡效果。动态组件的过渡,我们将在后面的内容讲到。)

我们把 v-if 改成 v-show,时间改为 1 秒,保存之后刷新网页查看。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>前端一万小时-Vue 中 CSS 动画原理</title>
  <script src="./vue.js"></script>
  <style>
    
    /* ❗️整理了 CSS 代码。 */
    .v-enter,
    .v-leave-to {
      opacity: 0;
    }
    
    .v-enter-active,
    .v-leave-active {
      transition: opacity 1s;
    } /* 2️⃣时间改为 1 秒。 */
    
  </style>
</head>
<body>
  <div id="root">
    <transition>
      
      <div v-show="show">Hello,前端一万小时</div> <!-- 1️⃣v-if 改成 v-show; -->
      
    </transition>
    <button @click="handleClick">切换</button>
  </div>
  <script>
    var vm = new Vue({
      el: "#root",
      data: {
        show: true
      },
      methods: {
        handleClick: function() {
          this.show = !this.show
        }
      }
    })
  </script>
</body>
</html>

(22)Vue 中的动画特效——① Vue 中的 CSS 动画原理 | Vue 基础理论实操

再次简短总结一下过渡动画的使用:

  1. 在想实现过渡动画的 DOM 元素外,用 transition 标签包裹起来;
  2. 在 CSS 中写上对应的样式。

祝好,qdywxs ♥ you!

转载自:https://juejin.cn/post/7223204251005386810
评论
请登录