(28)Vue 中的动画特效——⑦ Vue 中的动画封装 | Vue 基础理论实操

7,085 阅读2分钟
本文版权归 “公众号 | 前端一万小时” 所有,欢迎转载!

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

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

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



打开编辑器,准备好一份代码,点击“切换”显示/隐藏时有渐隐渐现的动画效果:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>前端一万小时-Vue 中的动画封装</title>
  <script src="./vue.js"></script>
  <style>
     .v-enter,
     .v-leave-to {
      opacity: 0;
     }

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

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

vue_28-01.gif

1 封装渐隐渐现动画效果

❓如何渐隐渐现的动画效果能够复用?

答:可以对渐隐渐现的动画效果进行封装。

<body>
  <div id="root">

    <fade :show="show"> <!-- 4️⃣使用 fade 组件:传一个 show 变量,它等于父组件的 show。 -->

      <!-- 2️⃣
			2️⃣-①:去除 div 外的 transition 标签; -->
      <div>Hello,前端一万小时</div>
      
    </fade>

    <button @click="handleBtnClick">切换</button>
  </div>

  <script>

    Vue.component("fade", { // 1️⃣新建名为 fade 的组件;
      
      props: ["show"], /*
      								 3️⃣
      								 3️⃣-①:接收父组件传来的 show;
                        */
      
      template: `
        <transition>
          <slot v-if="show"></slot>
        </transition>
      `  // 2️⃣-②:在模板中添加 transition 标签并增加 slot 插槽;
         // 3️⃣-②:在 slot 中通过 show 来判断内容是否显示;
    })

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

完成后,刷新页面查看效果:

vue_28-02.gif

2 使用封装好的渐隐渐现效果

❓封装之后,如何在另一个元素上使用?

答:使用方法很简单,可以分别传入两个 DOM 元素,然后两个元素都会有渐隐渐现效果。

<div id="root">

  <fade :show="show"> <!-- 1️⃣div 元素; -->
    <div>Hello,前端一万小时</div>
  </fade>

  <fade :show="show"> <!-- 2️⃣h1 元素。 -->
    <h1>Hello,前端一万小时</h1>
  </fade>

  <button @click="handleBtnClick">切换</button>
</div>

vue_28-03.gif

3 把样式一起封装进动画组件

❓如何可以调用动画组件并且不用再单独写 CSS 样式?

答:可以把样式一起封装到动画组件里,使用 JS 动画而不使用 CSS 动画。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>前端一万小时-Vue 中的动画封装</title>
  <script src="./vue.js"></script>

  <!-- 1️⃣使用 JS 动画,移除此处多余的 CSS 样式; -->
</head>
<body>
  <div id="root">
    <fade :show="show">
      <div>Hello,前端一万小时</div>
    </fade>
    <fade :show="show">
      <h1>Hello,前端一万小时</h1>
    </fade>
    <button @click="handleBtnClick">切换</button>
  </div>

  <script>
    Vue.component("fade", {
      props: ["show"],

      // 2️⃣给 transition 添加 before-enter 钩子执行 handleBeforeEnter 函数;
      // 4️⃣添加 enter 钩子,在 before-enter 钩子执行完成后执行 handleEnter 函数;
      template: `
        <transition @before-enter="handleBeforeEnter" @enter="handleEnter">
          <slot v-if="show"></slot>
        </transition>
      `,

      // 3️⃣在 fade 的 methods 中定义 handleBeforeEnter 函数:
      methods: {
        handleBeforeEnter: function(el) { // 3️⃣-①:handleBeforeEnter 接收一个 el 参数;
          el.style.color = "red" // 3️⃣-②:让元素的样式变为红色;
        },

        handleEnter: function(el, done) { // 4️⃣-①:handleEnter 接收 el 和 done 两个参数;
          
          setTimeout(() => {
            el.style.color = "green" // 4️⃣-②:让元素两秒后变为绿色;
            done() // 4️⃣-③:在动画结束时手动调用 done 回调函数;
          }, 2000)
          
        }
      }
    })

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

把动画样式封装进组件的效果,元素显示时先变红,2 秒后变成绿色:

vue_28-04.gif 这种类型的动画封装是比较推荐的,因为它可以完整把所有动画的实现封装在一个组件里面。而使用时,外部只需要调用组件,并且不需要再在全局中写 style 样式。

祝好,qdywxs ♥ you!