Try   HackMD

transition-group 元件

竹白記事本
Vue Transition|目錄

tags: Vue Transition 竹白的 Vue.js 學習筆記

大量元素的轉場

目前為止,都是針對單個節點,或是同一時間渲染多個節點中的一個。如果要針對由 v-for 產生的大量元素(例如:列表),就要改為使用 transition-group 元件。

transition-group 元件有以下幾個特點:

  • 不同於 <transition>,它會以一個真實元素呈現:預設為一個 <span>。可以通過 tag 特性更換為其他元素。
  • 轉場模式(in-outout-in)不可用,因為我們不再相互切換特有的元素。
  • 內部元素 總是需要 提供唯一的 key 屬性值。
  • CSS 轉場的類將會應用在內部的元素中,而不是這個組/容器本身。

1. 進入/離開的轉場

首先我們看一段程式碼:

<button v-on:click="add">Add</button>
<button v-on:click="remove">Remove</button>

<ul>
  <li v-for="item in items" :key="item" class="list-item">
    {{ item }}
</ul>

按下 Add 會隨機插入數字,按下 Remove 會隨機移除數字。

接下來我們改用 transition-group 元件,增加轉場效果。

transition-group 元件預設會有一個 <span> 的根元素,它會包住由 v-for 產生的多個元素當成其子元素。

我們透過 tag 特性,將其改成 <ul>

<transition-group name="list" tag="ul">
  <li v-for="item in items" v-bind:key="item" class="list-item">
    {{ item }}
  </li>
</transition-group>

並加上 CSS:

.list-enter,
.list-leave-to {
  opacity: 0;
  transform: translateY(100%);
}

.list-leave,
.list-enter-to {
  opacity: 1;
}

.list-enter-active,
.list-leave-active {
  transition: all 1s;
}

不過這個範例有一個明顯問題,當新增和移除元素的時候,周圍的元素會瞬間移動到他們的新佈局的位置,這會顯得不自然,我們將會在之後解決這個問題。

2. 排序轉場

transition-group 元件還有一個特殊之處。不僅可以進入和離開動畫,還可以改變定位。

v-move 特性,它會在元素的改變定位的過程中應用。像之前的列別名稱一樣,可以通過 name 屬性來自定義前綴,也可以通過 move-class 屬性手動設置。

v-move 對於設置轉場的切換時機和轉場曲線非常有用。

<button v-on:click="items.reverse()">Reverses</button>

<transition-group name="flip-list" tag="ul">
  <li 
  v-for="item in items"
  :key="item"
  class="list-item">{{ item }}
  </li>
</transition-group>
.flip-list-move {
  transition: transform 1s;
}
const vm = new Vue({
  el: '#app',
  data: {
    items: [1, 2, 3, 4, 5, 6, 7, 8, 9],
  },
});

Vue 使用了一個叫 FLIP 簡單的動畫隊列。使用 transforms 將元素從之前的位置平滑轉場新的位置。

讓我們修正上節不自然的的程式碼:

.list-move-active {
  position: absolute;
}

.list-move  {
  transition: 1s;
}

另外要注意,FLIP 轉場的元素不能設置為 display: inline。作為替代方案,可以設置為 display: inline-blockdisplay: flex-block 或者放置於 FlexBox 父容器中