(八)Vue - 过渡和动画

过滤的类名

vue 在插入、更新或者移除 DOM 时,提供多种不同方式的应用过渡效果。
Vue 提供了 transition 的封装组件,可以再某些条件下,给任何元素或组件添加进入或离开过渡动画。
学习过渡,我们必须要知道有哪些过渡的类名。

借用官方文档的一张图来讲解过渡的类名:
在这里插入图片描述在dom进入/离开的过渡中,会有 6 个 class 切换,我们可以理解为dom进入和离开的过渡,会存在6个class的钩子。

  1. v-enter:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。
  2. v-enter-active:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。
  3. v-enter-to:定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时 v-enter 被移除),在过渡/动画完成之后移除。
  4. v-leave:定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。
  5. v-leave-active:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。
  6. v-leave-to:定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave 被删除),在过渡/动画完成之后移除。
  <style>
    /* v-enter 【这是一个时间点】 是进入之前,元素的起始状态,此时还没有开始进入 */
    /* v-leave-to 【这是一个时间点】 是动画离开之后,离开的终止状态,此时,元素 动画已经结束了 */
    .v-enter,
    .v-leave-to {
      opacity: 0;
      transform: translateX(150px);
    }

    /* v-enter-active 【入场动画的时间段】 */
    /* v-leave-active 【离场动画的时间段】 */
    /* 设置持续时间和动画函数 */
    .v-enter-active,
    .v-leave-active{
      transition: all 0.8s ease;
    }
  </style>

<body>
  <div id="app">
    <input type="button" value="toggle" @click="flag=!flag">
    <!-- 使用Vue提供的 transition 元素,把 需要被动画控制的元素,包裹起来 -->
    <transition>
      <h3 v-if="flag">这个标签,用于体验过渡动画</h3>
    </transition>
  </div>

  <script>
    var vm = new Vue({
      el: '#app',
      data: {
        flag: false
      }
    });
  </script>
</body>

上面的代码示例是一个简单的进入离开过渡示例,我们只需要再过渡类名上做手脚,即可实现过渡效果;
其实当插入或删除包含在 transition 组件中的元素时,Vue 将会自动嗅探目标元素是否应用了 CSS 过渡或动画,如果是,会在恰当的时机添加/删除 相应的CSS 类名。

对于这些在过渡中切换的类名来说,如果你使用一个没有名字的 ,则 v- 是这些类名的默认前缀。如果你使用了 ,那么 v-enter 会替换为 my-transition-enter,其它类名同理。

自定义过渡的类名

上述例子中官方预设的过渡类名不够灵活,我们也可以不必使用官方预设的类名,而是自定义任意的过渡类名,
下面我们可以通过以下属性来自定义过渡类名:

enter-class
enter-active-class
enter-to-class (2.1.8+)
leave-class
leave-active-class
leave-to-class (2.1.8+)

这样非常方便我们结合第三方动画库使用,具体示例结合第三方类库解释。

使用第三方类实现过渡动画

由于vue支持自定义过渡类名,让我们非常方便的使用第三方动画类库,这里以animate.css的css动画库作为例子来介绍
送上官方链接:https://animate.style/
可以在官方链接里找寻自己想要的效果。

  <!--导入动画库 -->
<link rel="stylesheet" href="./lib/animate.css">
  <!-- 入场 bounceIn动画    离场 bounceOut动画 -->
<body>
    <!-- 点击按钮,让 h3 显示,再点击,让 h3 隐藏 -->
  <div id="app">
    <input type="button" value="toggle" @click="flag=!flag">

    <!-- 使用enter-active-class和leave-active-class属性,自定义我们的过渡类名,在这里使用动画库的类名 -->
    <!-- 这里需要添加animated的基础动画类,不然动画不生效 -->
    <transition enter-active-class="animated bounceIn" leave-active-class="animated bounceOut">
      <h3 v-if="flag">这是一个H3</h3>
    </transition>

    <!-- 使用 :duration="毫秒值" 来统一设置 入场 和 离场 时候的动画时长 -->
        <!-- 也可以直接将animated的基础动画类统一设置在元素上 -->
    <transition enter-active-class="bounceIn" leave-active-class="bounceOut" :duration="200">
      <h3 v-if="flag" class="animated">这是一个H3</h3>
    </transition>

    <!-- 使用  :duration="{ enter: 200, leave: 400 }"  来分别设置 入场的时长 和 离场的时长  -->
    <transition 
    enter-active-class="bounceIn" 
    leave-active-class="bounceOut" 
    :duration="{ enter: 200, leave: 400 }">
      <h3 v-if="flag" class="animated">这是一个H3</h3>
    </transition> 
  </div>

动画的钩子函数

我们可以再transition组件的属性中添加钩子函数

<transition
  v-on:before-enter="beforeEnter"
  v-on:enter="enter"
  v-on:after-enter="afterEnter"
  v-on:enter-cancelled="enterCancelled"

  v-on:before-leave="beforeLeave"
  v-on:leave="leave"
  v-on:after-leave="afterLeave"
  v-on:leave-cancelled="leaveCancelled"
>
  <!-- ... -->
</transition>

对应的是Vue对象中methods属性的钩子函数,我们可以理解为动画的生命周期钩子;
每个钩子所对应的动画周期就是其对应的字面意思,非常容易理解,下面以一个简单的例子来学习动画的钩子函数。


<body>
  <div id="app">
    <input type="button" value="开始动画" @click="flag=!flag">
    <!-- 使用 transition包裹需要执行动画的元素 -->
    <transition
      @before-enter="beforeEnter"
      @enter="enter"
      @after-enter="afterEnter">
      <div class="red-circle" v-show="flag"></div>
    </transition>
  </div>

  <script>
    var vm = new Vue({
      el: '#app',
      data: {
        flag: false
      },
      methods: {
        // 动画钩子函数的第一个参数:el,表示 要执行动画的那个DOM元素,是个原生的 JS DOM对象
        beforeEnter(el){
          // beforeEnter 表示动画入场之前,此时,动画尚未开始,可以 在 beforeEnter 中,设置元素开始动画之前的起始样式
          // 设置动画起始位置
          el.style.transform = "translate(0, 0)"
        },
        enter(el, done){
          //此方法如果不写,则没有动画效果,其并无其它作用,理解为会强制动画刷新;
          el.offsetWidth
          // enter 表示动画 开始之后的样式,这里,可以设置元素完成动画之后的,结束状态
          el.style.transform = "translate(150px, 450px)"
          el.style.transition = 'all 1s ease'

          // 这里的 done, 就是 afterEnter 这个函数,done 是 afterEnter 函数的引用,这里必须要调用done(),否则afterEnter会同步调用,afterEnter调用会稍延迟,显得动画不够连贯
          done()
        },
        afterEnter(el){
          // 动画完成之后,会调用 afterEnter
          this.flag = !this.flag
        }
      }
    });
  </script>
</body>

列表动画

针对列表,我们需要使用 ransition-group 组件来实现动画,其用法与transition组件类似

      <!-- 在实现列表过渡的时候,如果需要过渡的元素,是通过 v-for 循环渲染出来的,不能使用 transition 包裹,需要使用 transitionGroup -->
      <!-- 如果要为 v-for 循环创建的元素设置动画,必须为每一个 元素 设置 :key 属性 -->
      <!-- 给 ransition-group 添加 appear 属性,实现页面刚展示出来时候,入场时候的效果 -->
      <!-- 通过 为 transition-group 元素,设置 tag 属性,指定 transition-group 渲染为指定的元素,如果不指定 tag 属性,默认,渲染为 span 标签 -->
      <transition-group appear tag="ul">
        <li v-for="(item, i) in list" :key="item.id" @click="del(i)">
          {{item.id}} --- {{item.name}}
        </li>
      </transition-group>

当列表里元素位置发生变更后,周围元素会瞬间移动到新的位置,这样整体效果会不够平滑和友好。
为解决这个问题,我们可以使用 v-move属性,其特性与其他过渡属性一样;
其内部的实现,Vue 使用了一个叫 FLIP 简单的动画队列,使用 transforms 将元素从之前的位置平滑过渡新的位置。

    .v-enter,
    .v-leave-to {
      opacity: 0;
      transform: translateY(80px);
    }

    .v-enter-active,
    .v-leave-active {
      transition: all 0.6s ease;
    }

    /*  .v-move 和 .v-leave-active 配合使用,能够实现列表里动画元素周围的元素,也会有一个过渡动画移动到新的未知*/
    .v-move {
      transition: all 0.6s ease;
    }
    .v-leave-active{
      position: absolute;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值