zoukankan      html  css  js  c++  java
  • Vue一个案例引发「动画」的使用总结

    项目开发中动画有着很重要的作用,而且也是用到的地方非常多,例如:鼠标的进入离开,弹窗效果,组件的显示隐藏,列表的切换等等,可以说我们网页上的动画无处不在,也有人说了,这些东西也可以不使用动画。

    对,你说的没错可以不使用,但是,首先你要说服你的产品经理咱能不能简单点,不搞这么多虚的来点实际的,说完之后我估计你们俩得立马干起来,其次,在你的网页上不使用动画不够逼格啊,而且咱们的网页也不够生动,没有活力,由此可见动画的不可或缺性。

    上面只是开个玩笑,下面咱们进入主题,看看 Vue 中如何更好更简单的添加动画。

    首先,Vue 在插入,修改或者移除 DOM 时,提供了多种不同的添加动画的方法,在 Vue 中我们使用 <transition><transition-group> 组件时,Vue 会给我们提供一些内置的 CSS 类与 JS 钩子函数。

    先来看看我们要实现一个什么样子的案例效果

    图中的例子是一个非常常见的图片切换效果,不过在这个例子中我们只是单纯的实现图片的切换,看起来非常的生硬,没有任何的过渡效果,下面我们来给图片加一点动画的效果,让它看起来非常的有逼格。

    CSS 过渡

    <transition> 包裹的组件,在组件的不同阶段会产生不同的 class 类名进行切换

    • v-enter/v-leave:动画的第一帧
    • v-enter-acive/v-leave-active:动画运行的阶段,一些过渡属性会放置在这里,如:时间,延迟等
    • v-enter-to/v-leave-to:动画结束,最后一帧

    官网上的一张图片非常友好的展示了这个切换的过程。

    v- 是 Vue 中默认的类名前缀,我们在使用的过程中如果一直使用默认的命名方式的话,必然会导致一些冲突,所以 Vue 给我们提供了一个自定义命名的方案,我们只需要给 <transition> 添加一个 name 属性即可。

    既然我们知道了方法,我们就来给它加一个简单的动画。

    <template>
    <ul class="tabs-list">
      <li 
        v-for="tab in tabs"
        :key="tab.id"
        :class="{active: tabOn === tab.id}" 
      >
        <a
          @mouseover="tabOn = tab.id"
          :href="tab.url" target="_blank"
        >
          {{tab.name}}
          <transition name="flip">
            <img v-show="tabOn === tab.id" :src="tab.imgUrl">
          </transition>
        </a>
      </li>
    </ul>
    <template>
    <style lang="scss" scoped>
    .flip-enter-active {
      transition: transform 1s;
    }
    .flip-leave-active {
      transition: transform 1s;
    }
    .flip-enter,
    .flip-leave-to {
      transform: scaleY(0);
    }
    </style>

    CSS 动画

    与上面 CSS 过渡不同的是,我们这里说的 CSS 动画是利用 @keyframes 来创建与上面类似的动画效果。

    <style lang="scss" scoped>
    @keyframes scaleY-in {
      0% {
        transform: scaleY(0);
      }
      50% {
        transform: scaleY(0.5);
      }
      100% {
        transform: scaleY(1);
      }
    }
    .flip-enter-active {
      animation: scaleY-in 1s;
    }

    .flip-leave-active {
      animation: scaleY-in 1s reverse;
    }
    </style>
    使用第三方动画库

    Vue 中给我们提供了自定义 CSS 类名的方法,非常好的支持了与第三方动画库的结合。

    • enter-class / leave-class
    • enter-active-class / leave-active-class
    • enter-to-class / leave-to-class

    上面两个动画都是我们自己动手写出来的,但是有些时候我们自己手写的并不是那么完美,或者项目的时间比较紧张,这个时候选择第三方库就是一个比较好的方案。我们继续利用 Animate.css 动画库修改我们上面的例子。

    <transition 
        name="flip"
        enter-active-class="animated rotateIn"
        leave-active-class="animated rotateOut"
    >
        <img v-show="tabOn === tab.id" :src="tab.imgUrl">
    </transition>

    JavaScript 动画

    Vue 中还给我们提供了一些钩子函数,我们可以使用 JavaScript 钩子函数构建动画。

    <transition
      @before-enter="beforeEnter"
      @enter="enter"
      @after-enter="afterEnter"
      @enter-cancelled="enterCancelled"

      @before-leave="beforeLeave"
      @leave="leave"
      @after-leave="afterLeave"
      @leave-cancelled="leaveCancelled"
      :css="false"
    >
    </transition>

    所有钩子都会传入一个 el(元素)参数,enter/leave 函数还会传入一个 done 函数作为参数。它会告知我们的动画完成,我们绑定了 css 为 false,告诉组件跳过 CSS 的检测,使用 JavaScript。

    我们结合 Velocity.js 动画,来修改完成我们的动画效果。

    <transition 
        @enter="enter"
        @leave="leave"
        :css="false"
    >
        <img v-show="tabOn === tab.id" :src="tab.imgUrl">
    </transition>
    <script>
    methods: {
        enter(el, done) {
          Velocity(el, { scaleY: "0" });
          Velocity(el, { scaleY: "0.5" }, { duration: 1000 });
          Velocity(el, { scaleY: "1" }, { complete: done });
        },
        leave: function(el, done) {
          Velocity(el, { scaleY: "1" });
          Velocity(el, { scaleY: "0.5" }, { duration: 1000 });
          Velocity(el, { scaleY: "0" }, { complete: done });
        }
    }
    </script>
    过渡模式

    我们再来回头看看上面的例子,不管我们使用何种方式实现的动画,你会发现一个问题就是,动画在切换的时候两者(进入/离开)是同时进行的,有些时候,我们并不希望产生这种效果,对我们的动画效果非常的不友好,比如我们看看下面的这个例子。

    <template>
    <div class="translate-container" @click="clickHandler">
      <transition name="slide">
        <img v-if="isShow" src="./feature/03.jpg" key="first">
        <img v-else src="./feature/04.jpg" key="second">
      </transition>
    </div>
    </template>
    <script>
    export default {
      methods: {
        clickHandler() {
          this.isShow = !this.isShow;
        }
      }
    }
    </script>
    <style lang="scss" scoped>
        .slide-enter-active,
        .slide-leave-active {
          transition: all 0.5s;
        }
        .slide-leave-to,
        .slide-enter {
          transform: scaleY(0);
        }
    </style>

    很显然,这种是非常不好的效果,值得高兴的是 Vue 中给我们提供了一个解决方案-- 过渡模式,我们不需要增加额外的代码,只需要修改下特性即可。

    Vue 给我们提供了两种过渡模式。

    • in-out:新元素先进行过渡,完成之后当前元素过渡离开。
    • out-in:当前元素先进行过渡,完成之后新元素过渡进入

    过渡模式只会在相互切换的元素中才会生效

    <transition name="fade" mode="out-in"></transition>

    <transition name="fade" mode="in-out"></transition>

    下面我们就用过渡模式修改我们上面的案例。

    <transition name="slide" mode="out-in">
        <img v-if="isShow" src="./feature/03.jpg" key="first">
        <img v-else src="./feature/04.jpg" key="second">
    </transition>

    总结

    Vue 给我们提供了比较直观灵活的 API,方便我们在项目中添加动画的效果。

    Vue 中除了这些单元素的动画以外还提供了<transition-group> 给我的列表(使用v-for 时的场景)添加动画,喜欢动画的小伙伴可以动手去尝试绘制一些自己喜欢的动画。

    文中如有不足之处,欢迎留言指正,如果本文对你有帮助,欢迎转发点赞。

    关注我的微信公众号:六小登登,更多干货文章,欢迎一起交流。
    人人都可以成为高手。我是一个会技术,又写干货的码农。欢迎勾搭。

  • 相关阅读:
    MQTT TLS 加密传输
    python多进程并发redis
    各种消息队列的特点
    mqtt异步publish方法
    Numpy API Analysis
    Karma install steps for unit test of Angular JS app
    reinstall bower command
    Simulate getter in JavaScript by valueOf and toString method
    How to: Raise and Consume Events
    获取对象的类型信息 (JavaScript)
  • 原文地址:https://www.cnblogs.com/beevesnoodles/p/10026738.html
Copyright © 2011-2022 走看看