溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

vue2.0 中使用transition實現(xiàn)動畫效果使用心得

發(fā)布時間:2020-10-22 12:19:24 來源:腳本之家 閱讀:309 作者:lhb_11 欄目:web開發(fā)

實踐

這里將通過四個實踐小案例來體驗和學(xué)習(xí)css過渡,css動畫,javascript鉤子,列表過渡的應(yīng)用。至于案例用到的知識點就請自行學(xué)習(xí)官網(wǎng)文檔。

1.css過渡–實踐

先來看看demo效果:

vue2.0 中使用transition實現(xiàn)動畫效果使用心得

這個案例其實很簡單,通過一個transition來觸發(fā)多個子元素的過渡效果,我們只需要定義元素對應(yīng)的過渡效果就可以,其他事情vue會幫我們搞定,由此可以擴(kuò)展出其他酷炫的過渡場景效果。先來看看這個簡單案例的代碼實現(xiàn):

<template>
 <div class="app">
  <button @click="showMenu" class="btn">{{text}}</button>
  <transition name="move">
   <div class="menu" v-show="show">
    <div class="inner inner-1">1</div>
    <div class="inner inner-2">2</div>
    <div class="inner inner-3">3</div>
   </div>
  </transition>
 </div>
</template>

<script type="text/ecmascript-6">
 export default {
  data () {
   return {
    show: false
   };
  },
  methods: {
   showMenu () {
    this.show = !this.show;
   }
  },
  computed: {
   text () {
    return this.show ? '收' : '開';
   }
  }
 };
</script>

<style lang="stylus" rel="stylesheet/stylus">
 .app
  .btn
   position: fixed
   bottom: 50px
   right: 10px
   z-index: 10
   width: 50px
   height: 50px
   line-height: 50px
   border-radius: 50%
   border: none
   outline: none
   color: #fff
   font-size: 18px
   background: blue
  .menu
   position: fixed
   bottom: 50px
   right: 10px
   width: 50px
   height: 50px
   border-radius: 50%
   transition: all .7s ease-in
   &.move-enter-active
    .inner
     transform: translate3d(0, 0, 0)
     transition-timing-function: cubic-bezier(0, .57, .44, 1.97)
    .inner-1
     transition-delay: .1s
    .inner-2
     transition-delay: .2s
    .inner-3
     transition-delay: .3s
   &.move-enter, &.move-leave-active
    .inner
     transition-timing-function: ease-in-out
    .inner-1
     transform: translate3d(0, 60px, 0)
     transition-delay: .3s
    .inner-2
     transform: translate3d(40px, 40px, 0)
     transition-delay: .2s
    .inner-3
     transform: translate3d(60px, 0, 0)
     transition-delay: .1s
   .inner
    display: inline-block
    position: absolute
    width: 30px
    height: 30px
    line-height: 30px
    border-radius: 50%
    background: red
    text-align: center
    color: #fff
    transition: all .4s
   .inner-1
    top: -50px
    left: 10px
   .inner-2
    left: -30px
    top: -30px
   .inner-3
    left: -50px
    top: 10px
</style>

可以看到我們的代碼基本主要是完成css過渡效果的樣式,而觸發(fā)過渡效果只是簡單地通過一個click事件就搞定了,vue會自動嗅探目標(biāo)元素是否有 CSS 過渡或動畫,并在合適時添加/刪除 CSS 類名。那下一個demo就來簡單實現(xiàn)一下使用css animation 做過渡的效果。

2.css 動畫–實踐

先來看看demo效果:

vue2.0 中使用transition實現(xiàn)動畫效果使用心得

這個案例其實跟上面的demo差不多,不同之處在于過渡效果是使用css動畫來實現(xiàn),看下實現(xiàn)的代碼:

<template>
 <div class="app">
 <button @click="showball" class="btn">show</button>
  <transition name="move" type="animation">
   <div class="ball" v-show="show">
    <div class="inner"></div>
   </div>
  </transition>
 </div>
</template>

<script type="text/ecmascript-6">
 export default {
  data () {
   return {
    show: false
   };
  },
  methods: {
   showball () {
    this.show = !this.show;
   }
  }
 };
</script>

<style lang="stylus" rel="stylesheet/stylus">
 @keyframes shape-change {
  0%, 100% {
   border-radius: 50%
   background: red
  }
  50% {
   border-radius: 0
   background: blue
  }
 }

 @keyframes moveball-in {
  0% {
   transform: translate3d(300px,-200px,0)
  }
  50% {
   transform: translate3d(100px,-400px,0)
  }
  100% {
   transform: translate3d(0,0,0)
  }
 }
 @keyframes moveball-out {
  0% {
   transform: translate3d(0,0,0)
  }
  50% {
   transform: translate3d(100px,-400px,0)
  }
  100% {
   transform: translate3d(300px,-200px,0)
  }
 }
 .app
  .btn
   width: 40px
   height: 30px
   margin-top: 40px
   border: none
   outline: none
   background: red
   color: #fff
  .ball
   position: absolute
   bottom: 20px
   left: 20px
   width: 50px
   height: 50px
   transition: all 1s cubic-bezier(.22,-0.86,.97,.58)
   &.move-enter-active
    opacity: 1
    animation: moveball-in 1s
    .inner
     animation: shape-change 1s
   &.move-leave-active
    opacity: 0.8
    animation: moveball-out 1s
    .inner
     animation: shape-change 1s
   .inner
    display: inline-block
    width: 30px
    height: 30px
    border-radius: 50%
    background: red
    transition: all 1s linear
</style>

從css代碼可以看出,我們只是在vue過渡類名下加了不同的animation而已。官網(wǎng)文檔明確說明當(dāng)只使用transition或animation其中一種時,vue是能自動監(jiān)聽對應(yīng)的類型的,但是如果同一個元素同時使用兩種效果,就需要明確指定監(jiān)聽哪一種類型,不過官網(wǎng)并沒有給出具體的栗子。那其實這個demo已經(jīng)簡單地實現(xiàn)同時使用兩種類型的情況,可以看到有一個透明度的變化。但是假如animation里使用了transform,并且外面也使用了transform的話,那么元素在過渡的時候動畫效果就會有沖突,效果就有點出入了。

3.JavaScript鉤子 – 實踐

前兩個栗子都是有進(jìn)入和離開的過渡,但是如果一些場景只需要進(jìn)入過渡然后就結(jié)束了,那么這時就可以使用JavaScript鉤子結(jié)合CSS transitions/animations來實現(xiàn),當(dāng)然也可以單獨使用。看下demo:

vue2.0 中使用transition實現(xiàn)動畫效果使用心得

這個一個非常low的模擬炮彈發(fā)射的場景,可以看到小球有拋物線軌跡運動的過渡,而且發(fā)射出去就不會再回來了,那么這個demo就是使用了JavaScript鉤子結(jié)合css來實現(xiàn)的,接下來看下關(guān)鍵代碼:

<template>
 <div class="app">
  <div class="gun" @click="launch($event)"></div>
  <div class="shells-wrapper">
   <transition v-for="shell in shells" name="launch-shell" @before-enter="beforeEnter" @enter="enter" @after-enter="afterEnter">
   <div class="shell" v-show="shell.show">
    <div class="inner"></div>
   </div>
   </transition>
  </div>
  <div class="goal"></div>


  <!--小球第二種-->
 <div class="ball-container">
  <ul>
  <li v-for="(ball,index) in balls" :key="index">
   <transition :css="false" name="drop" @before-enter="beforeDrop" @enter="dropping" @after-enter="afterDrop">
   <div class="ball" v-show="ball.show">
    <div class="inner inner-hook"></div>
   </div>
   </transition>
  </li>
  </ul>
 </div>
 <!--小球 End-->
 </div>
</template>

首先,由于本身這個demo是一組元素的過渡,所以有些童鞋就會覺得用2.0提供的transition-group不就行了嘛。不過transition-group是列表過渡,我的理解是那一組元素是相關(guān)聯(lián)的、互相影響的,但是這個demo的元素每個都是獨立的,只不過是一組獨立的元素過渡,所以還是用transition比較合理,那使用v-for就可以實現(xiàn)一組相同過渡的元素啦。接下來看JavaScript鉤子怎么實現(xiàn)這個過渡:

export default {
  data () {
   return {
    shells: [
     {
      show: false
     },
     {
      show: false
     },
     {
      show: false
     }
    ]
   };
  },
  methods: {
   launch (event) {
    for (let i = 0; i < this.shells.length; i++) {
     let shell = this.shells[i];
     if (!shell.show) {
     shell.show = true;
     shell.target = event.target;
     return;
     }
    }
   },
   beforeEnter (el) {
    let count = this.shells.length;
    while (count--) {
     let shell = this.shells[count];
     if (shell.show) {
      let rect = shell.target.getBoundingClientRect();
      let left = rect.left - 32;
      let top = -(window.innerHeight - rect.top - 15);
      el.style.display = '';
      el.style.webkitTransform = `translate3d(0,${top}px,0)`;
      el.style.transform = `translate3d(0,${top}px,0)`;
      let inner = el.getElementsByClassName('inner')[0];
      inner.style.webkitTransform = `translate3d(${left}px,0,0)`;
      inner.style.transform = `translate3d(${left}px,0,0)`;
     }
    }
   },
   enter (el, done) {
    /* eslint-disable no-unused-vars */
    let refresh = el.offsetHeight;
    this.$nextTick(() => {
     el.style.webkitTransform = 'translate3d(0,0,0)';
     el.style.transform = 'translate3d(0,0,0)';
     let inner = el.getElementsByClassName('inner')[0];
     inner.style.webkitTransform = 'translate3d(0,0,0)';
     inner.style.transform = 'translate3d(0,0,0)';
    });
    done();
   },
   afterEnter (el) {
    let ball = this.shells[0];
    ball.show = false;
    el.style.display = 'none';
   }
  }
 };

css樣式代碼:

.ball-container
  .ball
  position: absolute
  left: 32px
  bottom: 22px
  z-index: 50
  transition: all 0.4s cubic-bezier(0.49, -0.29, 0.75, 0.41)
  .inner
   width: 16px
   height: 16px
   border-radius: 50%
   background: rgb(0, 160, 220)
   transition: all 0.4s linear

過渡元素就不需要為其添加vue的過渡css類名了,只需在元素本身添加transition即可,那vue在之前css過渡的時候會自動幫我們?nèi)ヌ砑訉?yīng)的類名來完成過渡效果,但是用javascript鉤子就需要我們自己完成這個始末狀態(tài)的設(shè)置了。當(dāng)我們點擊觸發(fā)一個過渡的時候,我們在beforeEnter里先拿到當(dāng)前元素的偏移位置,然后給過渡元素設(shè)置其起始位置,在enter里需要重新觸發(fā)下瀏覽器的重繪,然后在下一幀重新設(shè)置元素的結(jié)束位置,這時就會產(chǎn)生過渡效果,在過渡完成后我們將當(dāng)前元素隱藏即可。那剛才講到的列表過渡,接下來就是關(guān)于使用transition-group的一個小demo了。

4.transition-group – 實踐

先看下demo效果:

vue2.0 中使用transition實現(xiàn)動畫效果使用心得

其實就是個簡單的todo lists的小demo,可以看到,當(dāng)其中一個元素過渡的時候,會影響其他元素的過渡。當(dāng)然,刪除按鈕其實本身也是一個transition過渡,也就是說可以在transition-group里使用transition,看下相關(guān)代碼:

<template>
 <div class="app">
  <button @click="add" class="add-btn">+</button>
  <transition-group name="slide" tag="ul" class="list-wrapper">
   <li class="list" v-for="(item, index) in lists" v-touch:swipeleft="showBtn.bind(this, index)" v-touch:swiperight="hideBtn.bind(this, index)" :key="item">
    <span class="text">{{item.text}}</span>
    <transition name="move">
     <button class="del-btn" @click="delList(index)" v-show="item.show">刪除</button>
    </transition>
   </li>
  </transition-group>
 </div>
</template>

有個小坑的地方就是,之前看官網(wǎng)列表過渡的栗子,它是一個數(shù)組,元素都是數(shù)字,并且每一項都必須設(shè)置唯一的key值。所以我完成demo的時候就自作聰明地將索引值傳給key,結(jié)果過渡老是不對,后來換成對應(yīng)的item就正常了(生無可戀臉)。這個demo用到了vue-touch,雖然github上說不支持2.0版本了,但是有一個next分支是支持的,只需在項目下安裝它即可:

sudo npm install --save git: //github.com/vuejs/vue-touch.git#next

這里看下主要的樣式:

.list
 display: flex
 width: 100%
 height: 40px
 line-height: 40px
 margin-bottom: 10px
 color: #666
 font-size: 14px
 background: #eee
 transition: all .4s
 &.slide-move
  transition: transform 1s
 &.slide-enter
  transform: translate3d(-100%, 0, 0)
 &.slide-leave-active
  position: absolute
  transform: translate3d(-100%, 0, 0)
 &:last-child
  margin-bottom: 0
 .del-btn
  flex: 0 0 60px
  border: none
  outline: none
  color: #fff
  background: red
  transition: all .4s
  &.move-enter, &.move-leave-active
   transform: translate3d(70px, 0, 0)
 .text
  flex: 1
  padding-left: 20px

如果改變定位過渡的duration與進(jìn)入離開一樣的話,其實可以不用-move,這里設(shè)置-move的過渡的duration不同于元素進(jìn)入離開的duration產(chǎn)生一種速度差,看起來舒服點。而且-leave-active需要設(shè)置position: absolute才會有效果?,F(xiàn)在看來其實列表過渡也是很容易實現(xiàn)的。

ps:下面看下vue.js 2.* 使用transition實現(xiàn)動畫效果

<transition name="fade">
 <div class="detail" v-show="detailShow"></div>
</transition>
<script type="text/ecmascript-6">
 export default {
 };
</script>
<style lang="stylus" ref="sheetstyle/stylus">
 .fade-enter-active, .fade-leave-active 
 opacity:1
 transition: all 1.0s 
 background:rgba(7,17,27,0.8) 
 .fade-enter, .fade-leave-active 
 opacity: 0
 background:rgba(7,17,27,0)
</style>

總結(jié)

以上所述是小編給大家介紹的vue2.0 中使用transition實現(xiàn)動畫效果使用心得,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對億速云網(wǎng)站的支持!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI