自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

在Vue中創(chuàng)建可重用的 Transition

開發(fā) 前端
如果我們可以將它們封裝到組件中,并在多個(gè)項(xiàng)目中簡(jiǎn)單地重用它們,結(jié)果會(huì)怎樣呢?我們將介紹幾種定義transition的方法,并深入研究如何使它們真正可重用。

本文轉(zhuǎn)載自微信公眾號(hào)「大遷世界」,轉(zhuǎn)載本文請(qǐng)聯(lián)系大遷世界公眾號(hào)。

Vue.js中的transition確實(shí)很棒。毫無(wú)疑問,它們可以非常輕松地讓應(yīng)用程序栩栩如生,但是通常必須在每個(gè)項(xiàng)目中從頭開始編寫它們,甚至還需要引入animate.css之類的CSS庫(kù)來(lái)使它們功能更強(qiáng)大。

如果我們可以將它們封裝到組件中,并在多個(gè)項(xiàng)目中簡(jiǎn)單地重用它們,結(jié)果會(huì)怎樣呢?我們將介紹幾種定義transition的方法,并深入研究如何使它們真正可重用。

[[328523]]

原始transition組件和CSS

定義transition的最簡(jiǎn)單方法是使用transition·或transition-group組件。這需要為transition定義一個(gè)name`和一些CSS。

  1. <template> 
  2.   <div id="app"> 
  3.     <button v-on:click="show = !show"> 
  4.       Toggle 
  5.     </button> 
  6.     <transition name="fade"> 
  7.       <p v-if="show">hello</p> 
  8.     </transition> 
  9.   </div> 
  10. </template> 
  11. <script> 
  12. export default { 
  13.   name: "App", 
  14.   data() { 
  15.     return { 
  16.       show: true 
  17.     }; 
  18.   } 
  19. }; 
  20. </script> 
  21. <style> 
  22. .fade-enter-active, 
  23. .fade-leave-active { 
  24.   transition: opacity 0.3s; 
  25. .fade-enter, 
  26. .fade-leave-to { 
  27.   opacity: 0; 
  28. </style> 

 

看起來(lái)容易,對(duì)吧?然而,這種方法有一個(gè)問題。我們不能在另一個(gè)項(xiàng)目中真正重用這個(gè)transition。

封裝transition組件

如果我們將前面的邏輯封裝到一個(gè)組件中,并將其用作一個(gè)組件,結(jié)果會(huì)怎樣呢?

  1. // FadeTransition.vue 
  2. <template> 
  3.   <transition name="fade"> 
  4.     <slot></slot> 
  5.   </transition> 
  6. </template> 
  7. <script> 
  8. export default { 
  9.    
  10. }; 
  11. </script> 
  12. <style> 
  13. .fade-enter-active, 
  14. .fade-leave-active { 
  15.   transition: opacity 0.3s; 
  16. .fade-enter, 
  17. .fade-leave-to { 
  18.   opacity: 0; 
  19. </style> 
  20.  
  21. // App.vue 
  22.  
  23. <template> 
  24.   <div id="app"> 
  25.     <button v-on:click="show = !show"> 
  26.       Toggle transition 
  27.     </button> 
  28.     <fade-transition> 
  29.       <div v-if="show" class="box"></div> 
  30.     </fade-transition> 
  31.   </div> 
  32. </template> 
  33. <script>...</script> 
  34. <style>...</style> 

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

封裝的包裝器transition組件

幸運(yùn)的是,Vue 中有一個(gè)功能,使我們可以將用戶指定的所有額外props和監(jiān)聽器傳遞給我們的內(nèi)部標(biāo)簽/組件。如果你還不知道,則可以通過$attrs訪問額外傳遞的 props,并將它們與v-bind結(jié)合使用以將它們綁定為props。這同樣適用于通過$listeners進(jìn)行的事件,并通過v-on對(duì)其進(jìn)行應(yīng)用。

  1. // FadeTransition.vue 
  2.  
  3. <template> 
  4.   <transition name="fade" v-bind="$attrs" v-on="$listeners"> 
  5.     <slot></slot> 
  6.   </transition> 
  7. </template> 
  8. <script> 
  9. export default {}; 
  10. </script> 
  11. <style> 
  12. .fade-enter-active, 
  13. .fade-leave-active { 
  14.   transition: opacity 0.3s; 
  15. .fade-enter, 
  16. .fade-leave-to { 
  17.   opacity: 0; 
  18. </style> 
  19.  
  20. // App.vue 
  21.  
  22. ... 
  23.  
  24. <fade-transition mode="out-in"> 
  25.   <div key="blue" v-if="show" class="box"></div> 
  26.   <div key="red" v-else class="red-box"></div> 
  27. </fade-transition> 
  28.  
  29. ... 
 
 

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

現(xiàn)在,我們可以傳遞普通transition組件可以接受的任何事件和支持,這使得我們的組件更加可重用。但為什么不更進(jìn)一步,增加通過 prop 輕松定制持續(xù)時(shí)間的可能性。

顯式持續(xù)時(shí)間 prop

Vue 為transition組件提供了一個(gè)duration prop,然而,它是為更復(fù)雜的動(dòng)畫鏈接而設(shè)計(jì)的,它幫助 Vue 正確地將它們鏈接在一起。

在我們的案例中,我們真正需要的是通過組件prop控制CSS animation/transition。我們可以通過不在CSS中指定顯式的CSS動(dòng)畫持續(xù)時(shí)間,而是將其作為樣式來(lái)實(shí)現(xiàn)。我們可以借助transition hook來(lái)做到這一點(diǎn),該transition hook與組件生命周期 hook 非常相似,但是它們?cè)谶^渡所需元素之前和之后被調(diào)用。讓我們看看效果如何。

  1. // FadeTransition.vue 
  2.  
  3. <template> 
  4.   <transition name="fade" 
  5.               enter-active-class="fadeIn" 
  6.               leave-active-class="fadeOut" 
  7.               v-bind="$attrs" 
  8.               v-on="hooks"> 
  9.       <slot></slot> 
  10.   </transition> 
  11. </template> 
  12. <script> 
  13. export default { 
  14.   props: { 
  15.     duration: { 
  16.       type: Number, 
  17.       default: 300 
  18.     } 
  19.   }, 
  20.   computed: { 
  21.     hooks() { 
  22.       return { 
  23.         beforeEnter: this.setDuration, 
  24.         afterEnter: this.cleanUpDuration, 
  25.         beforeLeave: this.setDuration, 
  26.         afterLeave: this.cleanUpDuration, 
  27.         ...this.$listeners 
  28.       }; 
  29.     } 
  30.   }, 
  31.   methods: { 
  32.     setDuration(el) { 
  33.       el.style.animationDuration = `${this.duration}ms`; 
  34.     }, 
  35.     cleanUpDuration(el) { 
  36.       el.style.animationDuration = ""
  37.     } 
  38.   } 
  39. }; 
  40. </script> 
  41. <style> 
  42. @keyframes fadeIn { 
  43.   from { 
  44.     opacity: 0; 
  45.   } 
  46.   to { 
  47.     opacity: 1; 
  48.   } 
  49. .fadeIn { 
  50.   animation-name: fadeIn; 
  51. @keyframes fadeOut { 
  52.   from { 
  53.     opacity: 1; 
  54.   } 
  55.   to { 
  56.     opacity: 0; 
  57.   } 
  58. .fadeOut { 
  59.   animation-name: fadeOut; 
  60. </style> 

 

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

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

Transition group 支持

你想到的最直接的方法可能是創(chuàng)建一個(gè)新組件,比如fade-transition-group,然后將當(dāng)前transition標(biāo)簽替換為transition-group標(biāo)簽,以實(shí)現(xiàn) group transition。如果我們可以在相同的組件中這樣做,并公開一個(gè)將切換到transition-group實(shí)現(xiàn)的group prop,那會(huì)怎么樣呢?幸運(yùn)的是,我們可以通過render函數(shù)或component和is屬性來(lái)實(shí)現(xiàn)這一點(diǎn)。

  1. // FadeTransition.vue 
  2.  
  3. <template> 
  4.   <component :is="type" 
  5.              :tag="tag" 
  6.              enter-active-class="fadeIn" 
  7.              leave-active-class="fadeOut" 
  8.              move-class="fade-move" 
  9.              v-bind="$attrs" 
  10.              v-on="hooks"> 
  11.       <slot></slot> 
  12.   </component> 
  13. </template> 
  14. <script> 
  15. export default { 
  16.   props: { 
  17.     duration: { 
  18.       type: Number, 
  19.       default: 300 
  20.     }, 
  21.     group: { 
  22.       type: Boolean, 
  23.       default: false 
  24.     }, 
  25.     tag: { 
  26.       type: String, 
  27.       default: "div" 
  28.     } 
  29.   }, 
  30.   computed: { 
  31.     type() { 
  32.       return this.group ? "transition-group" : "transition"; 
  33.     }, 
  34.     hooks() { 
  35.       return { 
  36.         beforeEnter: this.setDuration, 
  37.         afterEnter: this.cleanUpDuration, 
  38.         beforeLeave: this.setDuration, 
  39.         afterLeave: this.cleanUpDuration, 
  40.         leave: this.setAbsolutePosition, 
  41.         ...this.$listeners 
  42.       }; 
  43.     } 
  44.   }, 
  45.   methods: { 
  46.     setDuration(el) { 
  47.       el.style.animationDuration = `${this.duration}ms`; 
  48.     }, 
  49.     cleanUpDuration(el) { 
  50.       el.style.animationDuration = ""
  51.     }, 
  52.     setAbsolutePosition(el) { 
  53.       if (this.group) { 
  54.         el.style.position = "absolute"
  55.       } 
  56.     } 
  57.   } 
  58. }; 
  59. </script> 
  60. <style> 
  61. @keyframes fadeIn { 
  62.   from { 
  63.     opacity: 0; 
  64.   } 
  65.   to { 
  66.     opacity: 1; 
  67.   } 
  68. .fadeIn { 
  69.   animation-name: fadeIn; 
  70. @keyframes fadeOut { 
  71.   from { 
  72.     opacity: 1; 
  73.   } 
  74.   to { 
  75.     opacity: 0; 
  76.   } 
  77. .fadeOut { 
  78.   animation-name: fadeOut; 
  79. .fade-move { 
  80.   transition: transform 0.3s ease-out; 
  81. </style> 
  82.  
  83. // App.vue 
  84.  
  85. ... 
  86.  
  87. <div class="box-wrapper"> 
  88.   <fade-transition group :duration="300"> 
  89.     <div class="box" 
  90.          v-for="(item, index) in list" 
  91.          @click="remove(index)" 
  92.          :key="item" 
  93.      > 
  94.     </div> 
  95.   </fade-transition> 
  96. </div> 
  97.  
  98. ... 

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

 

[文檔中][6]介紹了一個(gè)帶有transition-group元素的警告。我們基本上必須在元素離開時(shí)將每個(gè)項(xiàng)目的定位設(shè)置為absolute,以實(shí)現(xiàn)其他項(xiàng)目的平滑移動(dòng)動(dòng)畫。我們也必須添加一個(gè)move-class并手動(dòng)指定過渡持續(xù)時(shí)間,因?yàn)闆]有用于移動(dòng)的 JS hook。我們將這些調(diào)整添加到我們的上一個(gè)示例中。

再做一些調(diào)整,通過在mixin中提取 JS 邏輯,我們可以將其應(yīng)用于輕松創(chuàng)建新的transition組件,只需將其放入下一個(gè)項(xiàng)目中即可。

Vue Transition

在此之前描述的所有內(nèi)容基本上都是這個(gè)小型 [transition 集合][7]所包含的內(nèi)容。它有 10 個(gè)封裝的transition組件,每個(gè)約1kb(縮小)。我認(rèn)為它非常方便,可以輕松地在不同的項(xiàng)目中使用。你可以試一試:)

總結(jié)

我們從一個(gè)基本的過渡示例開始,并最終通過可調(diào)整的持續(xù)時(shí)間和transition-group支持來(lái)創(chuàng)建可重用的過渡組件。我們可以使用這些技巧根據(jù)并根據(jù)自身的需求創(chuàng)建自己的過渡組件。希望讀者從本文中學(xué)到了一些知識(shí),并且可以幫助你們建立功能更好的過渡組件。

 

 

 

 

 

責(zé)任編輯:趙寧寧 來(lái)源: 大遷世界
相關(guān)推薦

2023-10-17 07:23:00

Vue組件代碼

2024-06-13 10:11:33

WPFCommand命令模式

2024-01-03 08:00:00

Java軟件開發(fā)代碼

2011-07-21 13:24:14

java

2023-11-08 13:55:27

2018-11-08 15:50:18

前端Javascript重用性

2011-04-12 16:01:04

MySQL查詢編寫

2010-06-09 09:15:58

JSF 2Ajax組件

2013-04-23 09:14:22

可重用云工具Java安全框架云中間件

2013-04-23 09:24:51

2013-12-04 14:19:40

JavaScript代碼重用

2011-07-12 15:45:29

java

2009-06-23 14:18:00

Java代碼可重用性

2023-06-15 09:02:14

Python模塊和包

2021-06-26 06:29:14

Vue 2Vue 3開發(fā)

2022-07-05 09:27:35

Iframe前端平臺(tái)架構(gòu)

2020-11-02 11:33:52

ReactVue應(yīng)用

2021-08-28 10:06:29

VueJavascript應(yīng)用

2024-06-28 01:13:59

工具C#代碼

2009-03-13 15:24:50

catchDisposeWCF
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)