Vue动画

作者: 译方设计 | 来源:发表于2018-11-28 07:41 被阅读94次

    首先,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>
    
    image

    很显然,这种是非常不好的效果,值得高兴的是 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动画

        本文链接:https://www.haomeiwen.com/subject/izboqqtx.html