<em id="09ttv"></em>
    <sup id="09ttv"><pre id="09ttv"></pre></sup>
    <dd id="09ttv"></dd>

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

          2020-5-21    seo達(dá)人

          原始transition組件和CSS

          定義transition的最簡單方法是使用transition·或transition-group 組件。這需要為transition定義一個(gè)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>

          圖片描述


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


          封裝transition組件

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


          // FadeTransition.vue

          <template>

           <transition name="fade">

             <slot></slot>

           </transition>

          </template>

          <script>

          export default {

           

          };

          </script>

          <style>

          .fade-enter-active,

          .fade-leave-active {

           transition: opacity 0.3s;

          }

          .fade-enter,

          .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>

          圖片描述


          通過在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對其進(jìn)行應(yīng)用。


          // 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-active {

           transition: opacity 0.3s;

          }

          .fade-enter,

          .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>


          ...

          圖片描述


          完整事例地址:https://codesandbox.io/s/yjl1...


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


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

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


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


          // 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>

          圖片描述


          完整事例地址:https://codesandbox.io/s/j4qn...


          現(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,那會怎么樣呢?幸運(yùn)的是,我們可以通過render函數(shù)或component和is屬性來實(shí)現(xiàn)這一點(diǎn)。


          // 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,

                 afterEnter: this.cleanUpDuration,

                 beforeLeave: this.setDuration,

                 afterLeave: this.cleanUpDuration,

                 leave: this.setAbsolutePosition,

                 ...this.$listeners

               };

             }

           },

           methods: {

             setDuration(el) {

               el.style.animationDuration = `${this.duration}ms`;

             },

             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>


          ...

          圖片描述


          完整事例地址:https://codesandbox.io/s/pk9r...


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


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


          Vue Transition

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


          總結(jié)

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

          日歷

          鏈接

          個(gè)人資料

          存檔

          亚洲女久久久噜噜噜熟女| 91麻精品国产91久久久久| 狠狠色伊人久久精品综合网| 久久国产高清一区二区三区| 国产精品成人久久久久久久| 一级女性全黄久久生活片免费 | 久久人妻AV中文字幕| 久久精品一区二区国产| 99久久99这里只有免费费精品| 精品久久久无码人妻中文字幕豆芽 | 国产巨作麻豆欧美亚洲综合久久 | 国产人久久人人人人爽| segui久久国产精品| 欧美午夜精品久久久久免费视| 久久精品国产99国产精品| 国产91久久精品一区二区| 国产一区二区精品久久凹凸| 亚洲va久久久噜噜噜久久 | 狠狠色婷婷久久综合频道日韩| 久久国产成人| 久久国产高潮流白浆免费观看| 久久综合久久自在自线精品自| 久久人人爽人人爽AV片| 久久久久无码中| 国产AV影片久久久久久| 国产精品久久自在自线观看| 久久热这里只有精品在线观看| 久久97久久97精品免视看秋霞| 久久美女网站免费| 久久香蕉国产线看观看乱码| 麻豆AV一区二区三区久久| 久久精品极品盛宴观看| 久久亚洲AV无码精品色午夜| 亚洲国产精品无码久久一区二区| 久久一区二区三区免费| 狠狠色综合网站久久久久久久| 久久狠狠色狠狠色综合| 久久96国产精品久久久| 99久久久久| 午夜精品久久久久久| 99久久婷婷免费国产综合精品|