1. 程式人生 > 程式設計 >在Vue中建立可重用的 Transition的方法

在Vue中建立可重用的 Transition的方法

Vue.js中的transition確實很棒。毫無疑問,它們可以非常輕鬆地讓應用程式栩栩如生,但是通常必須在每個專案中從頭開始編寫它們,甚至還需要引入animate.css之類的CSS庫來使它們功能更強大。

如果我們可以將它們封裝到元件中,並在多個專案中簡單地重用它們,結果會怎樣呢?我們將介紹幾種定義transition的方法,並深入研究如何使它們真正可重用。

在Vue中建立可重用的 Transition的方法

原始transition元件和CSS

定義transition的最簡單方法是使用transition·或transition-group元件。這需要為transition定義一個name`和一些CSS。

<template> 
 <div id="app"> 
 <button v-on:click="show = !show"> 
  Toggle 
 </button> 
 <transition name="fade"> 
  <p v-if="show">hello</p> 
 </transition> 
 </div> 
</template> 
<script> 
export default { 
 name: "App",data() { 
 return { 
  show: true 
 }; 
 } 
}; 
</script> 
<style> 
.fade-enter-active,.fade-leave-active { 
 transition: opacity 0.3s; 
} 
.fade-enter,.fade-leave-to { 
 opacity: 0; 
} 
</style> 

在Vue中建立可重用的 Transition的方法

看起來容易,對吧?然而,這種方法有一個問題。我們不能在另一個專案中真正重用這個transition。

封裝transition元件

如果我們將前面的邏輯封裝到一個元件中,並將其用作一個元件,結果會怎樣呢?

// FadeTransition.vue 
<template> 
 <transition name="fade"> 
 <slot></slot> 
 </transition> 
</template> 
<script> 
export default { 
 
}; 
</script> 
<style> 
.fade-enter-active,.fade-leave-to { 
 opacity: 0; 
} 
</style> 
 
// App.vue 
 
<template> 
 <div id="app"> 
 <button v-on:click="show = !show"> 
  Toggle transition 
 </button> 
 <fade-transition> 
  <div v-if="show" class="box"></div> 
 </fade-transition> 
 </div> 
</template> 
<script>...</script> 
<style>...</style> 

在Vue中建立可重用的 Transition的方法

通過在transition元件中提供一個slot,我們幾乎可以像使用基本transition元件一樣使用它。這比前面的例子稍微好一點,但是如果我們想要傳遞其他特定於transition的prop,比如mode或者一些hook,該怎麼辦呢

封裝的包裝器transition元件

幸運的是,Vue 中有一個功能,使我們可以將使用者指定的所有額外props和監聽器傳遞給我們的內部標籤/元件。如果你還不知道,則可以通過$attrs訪問額外傳遞的 props,並將它們與v-bind結合使用以將它們繫結為props。這同樣適用於通過$listeners進行的事件,並通過v-on對其進行應用。

// FadeTransition.vue 
 
<template> 
 <transition name="fade" v-bind="$attrs" v-on="$listeners"> 
 <slot></slot> 
 </transition> 
</template> 
<script> 
export default {}; 
</script> 
<style> 
.fade-enter-active,.fade-leave-to { 
 opacity: 0; 
} 
</style> 
 
// App.vue 
 
... 
 
<fade-transition mode="out-in"> 
 <div key="blue" v-if="show" class="box"></div> 
 <div key="red" v-else class="red-box"></div> 
</fade-transition> 
 
... 

在Vue中建立可重用的 Transition的方法

「完整事例地址:https://codesandbox.io/s/yjl1wjyoy1?from-embed 」

現在,我們可以傳遞普通transition元件可以接受的任何事件和支援,這使得我們的元件更加可重用。但為什麼不更進一步,增加通過 prop 輕鬆定製持續時間的可能性。

顯式持續時間 prop

Vue 為transition元件提供了一個duration prop,然而,它是為更復雜的動畫連結而設計的,它幫助 Vue 正確地將它們連結在一起。

在我們的案例中,我們真正需要的是通過元件prop控制CSS animation/transition。我們可以通過不在CSS中指定顯式的CSS動畫持續時間,而是將其作為樣式來實現。我們可以藉助transition hook來做到這一點,該transition hook與元件生命週期 hook 非常相似,但是它們在過渡所需元素之前和之後被呼叫。讓我們看看效果如何。

// FadeTransition.vue 
 
<template> 
 <transition name="fade" 
    enter-active-class="fadeIn" 
    leave-active-class="fadeOut" 
    v-bind="$attrs" 
    v-on="hooks"> 
  <slot></slot> 
 </transition> 
</template> 
<script> 
export default { 
 props: { 
 duration: { 
  type: Number,default: 300 
 } 
 },computed: { 
 hooks() { 
  return { 
  beforeEnter: this.setDuration,afterEnter: this.cleanUpDuration,beforeLeave: this.setDuration,afterLeave: this.cleanUpDuration,...this.$listeners 
  }; 
 } 
 },methods: { 
 setDuration(el) { 
  el.style.animationDuration = `${this.duration}ms`; 
 },cleanUpDuration(el) { 
  el.style.animationDuration = ""; 
 } 
 } 
}; 
</script> 
<style> 
@keyframes fadeIn { 
 from { 
 opacity: 0; 
 } 
 to { 
 opacity: 1; 
 } 
} 
.fadeIn { 
 animation-name: fadeIn; 
} 
@keyframes fadeOut { 
 from { 
 opacity: 1; 
 } 
 to { 
 opacity: 0; 
 } 
} 
.fadeOut { 
 animation-name: fadeOut; 
} 
</style> 

在Vue中建立可重用的 Transition的方法

「完整事例地址:https://codesandbox.io/s/j4qnjvmwz9?from-embed 」

現在,我們可以控制實際的可見過渡時間,這使我們可重用的過渡變得靈活且易於使用。但是,如何過渡多個元素(如列表項)呢?

Transition group 支援

你想到的最直接的方法可能是建立一個新元件,比如fade-transition-group,然後將當前transition標籤替換為transition-group標籤,以實現 group transition。如果我們可以在相同的元件中這樣做,並公開一個將切換到transition-group實現的group prop,那會怎麼樣呢?幸運的是,我們可以通過render函式或component和is屬性來實現這一點。

// FadeTransition.vue 
 
<template> 
 <component :is="type" 
    :tag="tag" 
    enter-active-class="fadeIn" 
    leave-active-class="fadeOut" 
    move-class="fade-move" 
    v-bind="$attrs" 
    v-on="hooks"> 
  <slot></slot> 
 </component> 
</template> 
<script> 
export default { 
 props: { 
 duration: { 
  type: Number,default: 300 
 },group: { 
  type: Boolean,default: false 
 },tag: { 
  type: String,default: "div" 
 } 
 },computed: { 
 type() { 
  return this.group ? "transition-group" : "transition"; 
 },hooks() { 
  return { 
  beforeEnter: this.setDuration,leave: this.setAbsolutePosition,cleanUpDuration(el) { 
  el.style.animationDuration = ""; 
 },setAbsolutePosition(el) { 
  if (this.group) { 
  el.style.position = "absolute"; 
  } 
 } 
 } 
}; 
</script> 
<style> 
@keyframes fadeIn { 
 from { 
 opacity: 0; 
 } 
 to { 
 opacity: 1; 
 } 
} 
.fadeIn { 
 animation-name: fadeIn; 
} 
@keyframes fadeOut { 
 from { 
 opacity: 1; 
 } 
 to { 
 opacity: 0; 
 } 
} 
.fadeOut { 
 animation-name: fadeOut; 
} 
.fade-move { 
 transition: transform 0.3s ease-out; 
} 
</style> 
 
// App.vue 
 
... 
 
<div class="box-wrapper"> 
 <fade-transition group :duration="300"> 
 <div class="box" 
   v-for="(item,index) in list" 
   @click="remove(index)" 
   :key="item" 
  > 
 </div> 
 </fade-transition> 
</div> 
 
... 

在Vue中建立可重用的 Transition的方法

「完整事例地址:https://codesandbox.io/s/pk9r5j2257?from-embed 」

[文件中][6]介紹了一個帶有transition-group元素的警告。我們基本上必須在元素離開時將每個專案的定位設定為absolute,以實現其他專案的平滑移動動畫。我們也必須新增一個move-class並手動指定過渡持續時間,因為沒有用於移動的 JS hook。我們將這些調整新增到我們的上一個示例中。

再做一些調整,通過在mixin中提取 JS 邏輯,我們可以將其應用於輕鬆建立新的transition元件,只需將其放入下一個專案中即可。

Vue Transition

在此之前描述的所有內容基本上都是這個小型 [transition 集合][7]所包含的內容。它有 10 個封裝的transition元件,每個約1kb(縮小)。我認為它非常方便,可以輕鬆地在不同的專案中使用。你可以試一試:)

總結

我們從一個基本的過渡示例開始,並最終通過可調整的持續時間和transition-group支援來建立可重用的過渡元件。我們可以使用這些技巧根據並根據自身的需求建立自己的過渡元件。希望讀者從本文中學到了一些知識,並且可以幫助你們建立功能更好的過渡元件。

到此這篇關於在Vue中建立可重用的 Transition的方法的文章就介紹到這了,更多相關vue建立Transition內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!