前言

记一次vue 组件中使用 transition 和 transition-group 设置过渡动画,总结来说可分为分为 name 版, js 钩子操作类名版, js 钩子操作行内样式版...

template模板结构

  // 单个元素    <transition name="自定义名字">      <p v-if="show">hello</p>    </transition>  // 列表元素: 注意group的直接子元素是v-for渲染出来的    <ul class="list">      <transition-group name="list">        <li v-for="(item, index) in gameList" :key="item.id">          <app-horizontal :itemData="item"></app-horizontal>        </li>      </transition-group>    </ul>

name 版,name 为组件中的属性

出现的过程: name-enter(初始态) => name-enter-active(中间态) => name-enter-to(终止态)消失的过程: name-leave => name-leave-active => name-leave-to

以进场过渡动画为例子

我们可以分别设置 enter 阶段 和 enter-to 阶段的动画  1.设置进入时需要过渡的属性  .name-enter  {    opacity: 0;    transform: translateY(30px)  }  2.然后在 name-enter-active中设置过渡时间  .name-enter-active {    transition: all .3s;  }  3.最后在 name-enter-to 中写上终止态属性    其实终止态的opacity: 1;transform: none; 是默认的,可以不用写  .name-enter-to {    opacity: 1;    transform: translateY(0);  }  如果要给列表中的元素设置交错的效果, 元素不多的话可以添加 delay 属性  .name-enter-active:nth-child(3n+1) {    transition-delay: 0s;  }  .name-enter-active:nth-child(3n+2) {    transition-delay: .1s;  }  .name-enter-active:nth-child(3n+3) {    transition-delay: .2s;  }  离场动画同理...

js 钩子实现过渡动画: 通过操作类名; 就是 name 版的 js 实现

// 例如实现上述列表依次显示  <ul class="list">    <transition-group      v-bind:css="false"      v-on:before-enter="beforeEnter"      v-on:enter="enter"      v-on:after-enter="afterEnter">      <li v-for="(item, index) in gameList"         :key="item.id"         :data-delay="index*100"       >          <app-horizontal :itemData="item"></app-horizontal>      </li>    </transition-group>  </ul>    //   methods: {    // 事先定义上述类名    // 在beforeEnter enter afterEnter 钩子中手动操作上述类名        // 初始态    beforeEnter(dom) {      dom.classList.add('list-enter', 'list-enter-active');    },    // 中间态    enter(dom,done) {      // 通过 setTimeout + dataset 实现过渡      let delay = dom.dataset.delay;      setTimeout(function () {        dom.classList.remove('list-enter');        dom.classList.add('list-enter-to');        //监听 transitionend 事件        var transitionend = window.ontransitionend ? "transitionend" : "webkitTransitionEnd";        dom.addEventListener(transitionend, function onEnd() {          // 移除事件          dom.removeEventListener(transitionend, onEnd);          //调用done(),表示动画已完成          done()        });      }, delay)    },    // 终止态    afterEnter(dom) {      dom.classList.remove('list-enter-to', 'list-enter-active');    }  }

js 钩子过渡动画: 通过操作行内属性, 自定义动画

   <ul class="list">    <transition-group      v-bind:css="false"      v-on:before-enter="beforeEnter"      v-on:enter="enter"      v-on:after-enter="afterEnter">      <li v-for="(item, index) in gameList"         :key="item.id"         :data-delay="index*100"        data-y = "100%"       >          <app-horizontal :itemData="item"></app-horizontal>      </li>    </transition-group>  </ul>    // 对应的操作方法; 添加自定义的 dataset,给dom设置css样式;根据需求添加   methods: {     // 初始态    beforeEnter(dom) {      let { x = 0, y = 0, opacity = 0 } = dom.dataset;      dom.style.cssText = `transition: .3s;opacity: ${opacity};transform: translateX(${x}) translateY(${y});`;    },    // 中间态    enter(dom,done) {      let delay = dom.dataset.delay;      setTimeout(function () {        dom.style.cssText = `transition: .3s;opacity: 1;transform: translateX(0) translateY(0);`;        //监听 transitionend 事件        var transitionend = window.ontransitionend ? "transitionend" : "webkitTransitionEnd";        dom.addEventListener(transitionend, function onEnd() {             dom.removeEventListener(transitionend, onEnd);             done();         });      }, delay)    },    // 终止态    afterEnter(dom) {      dom.style.cssText = "";    }  }

这里记录一下监听css3的animation动画和transition事件:

webkit-animation动画有三个事件:    开始事件: webkitAnimationStart    结束事件: webkitAnimationEnd    重复运动事件: webkitAnimationIterationcss3的过渡属性transition: 一个事件    过渡结束: webkitTransitionEnd