Vue.也提供了動畫處理的元件,針對元件或者元素節點中加入class然後再自行移除,我們稱之為漸變。
Vue.js將漸變的效果封裝成一個<transition>元件,再由我們自行定義進入enter和離開leave的效果,並提供了對應的class讓我們使用。
使用情境基本上分為:
Vue.js提供對應的class如下:enter(顯示)
v-enter:定義再進場之前的樣式。
v-enter-active:定義再進場過程的樣式。
v-enter-to:定義再進場結束時的樣式leave(消失)
v-leave:定義再退場之前的樣式。
v-leave-active:定義在退場過程的樣式。
v-leave-to:定義在退場結束時的樣式
接著來看一下簡單的程式碼:
<style>
    .v-enter-active,
    .v-leave-active {
      transition: opacity 1s;
    }
    .v-enter,
    .v-leave-to {
      opacity: 0;
    }
  </style>
</head>
<body>
  <div id="app">
    <button @click="show = !show">Toggle</button>
    <transition>
      <div v-show="show">Good Day</div>
    </transition>
  </div>
  <script>
    new Vue({
      el: '#app',
      data: {
        show: true
      }
    });
  </script>
</body>
透過上述的例子我們可以得知,我們將需要漸變的元件用<transition>包起來,就可以達到我們要的效果了!
在<style>裡面,我們發現都是以.v-開頭的,這是預設的統一樣式,我們也可以透過在<transition>加入name的屬性<transition name="">來設定多組不同的樣式:
 <style>
    .fade-enter-active,
    .fade-leave-active {
      transition: opacity 1s;
    }
    .fade-enter,
    .fade-leave-to {
      opacity: 0;
    }
    .slide-enter-active {
      transition: all .3s ease;
    }
    .slide-leave-active {
      transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0);
    }
    .slide-enter,
    .slide-leave-to {
      transform: translateX(10px);
      opacity: 0;
    }
  </style>
<body>
  <div id="app">
    <button @click="show = !show">Toggle</button>
    <transition name="fade">
      <div v-show="show">I'm fade</div>
    </transition>
    <transition name="slide">
      <div v-show="show">I'm slide</div>
    </transition>
  </div>
  <script>
    new Vue({
      el: '#app',
      data: {
        show: true
      }
    });
  </script>
</body>
上述範例我們在兩組<transition>加入了個別的name並定義對應的漸變動畫(style裡面的class)
我們可以用v-if和v-else來對多個元素做漸變的切換,但要注意的是,要記得加上key屬性,來告訴Vue.js,這個元素需要重新渲染:
<style>
    .fade-enter-active,
    .fade-leave-active {
      transition: opacity 1s;
    }
    .fade-enter,
    .fade-leave-to {
      opacity: 0;
    }
  </style>
</head>
<body>
  <div id="app">
    <button @click="show = !show">Toggle</button>
    <transition name="fade">
      <div v-if="show" key="fade1">I'm here</div>
      <div v-else key="fade2">Now you can't see me</div>
    </transition>
  </div>
  <script>
    new Vue({
      el: '#app',
      data: {
        show: true
      }
    });
  </script>
</body>
這邊可以看到我們在v-if加上key="fade1",v-else加上key="fade2。可以試看看將key拿掉,看看效果。
在多個元件切換就不需要key屬性,用is搭配<component>即可~
<body>
  <div id="app">
    <input v-model="view" type="radio" value="v-a" id="a" name="view"><label for="a">A選項</label>
    <input v-model="view" type="radio" value="v-b" id="b" name="view"><label for="b">B選項</label>
    <input v-model="view" type="radio" value="v-c" id="c" name="view"><label for="c">C選項</label>
    <transition name="fade">
      <component :is="view"></component>
    </transition>
  </div>
  <script>
    new Vue({
      el: '#app',
      data: {
        view: 'v-a'
      },
      components: {
        'v-a': {
          template: `<div>PS4</div>`
        },
        'v-b': {
          template: `<div>PS5</div>`
        },
        'v-c': {
          template: `<div>Switch</div>`
        }
      }
    });
  </script>
</body>
上述範例可以看到在<component>元件裡面多了:is來控制。
Vue.js的漸變效果除了預設的in-out也可以切換成out-in
語法是在<transition>裡面加上mode="out-in",<transition name="fade" mode="out-in">
可以更改上述的範例來看看效果的差別呦。
上述提到的<transition>只能用於單一節點的情況下使用,如果我們要控制列表之類的有多個節點的則需要使用<transition-group>。<transition-group>會渲染一個真實的元素,預設為<span>,如果要更改可以透過tag屬性更換為其他的元素。在內部元素每個都需要提供對應的key。<transition-group>中不只支援開始和離開的動畫,還支援定位改變的動畫:v-move(也可以自己定義class名稱)。
來看例子吧:
<style>
    .list-enter-active,
    .list-leave-active {
      transition: all 1s;
    }
    .list-enter,
    .list-leave-to {
      opacity: 0;
      transform: translateY(30px);
    }
  </style>
</head>
<body>
  <div id="app">
    <button @click="add">Add</button>
    <button @click="remove">Remove</button>
    <transition-group name="list" tag="ul">
      <li v-for="item in items" :key="item" class="list-item">
        {{ item }}
      </li>
    </transition-group>
  </div>
  <script>
    new Vue({
      el: '#app',
      data: {
        items: [1, 2, 3, 4, 5, 6, 7, 8, 9],
        nextNum: 10
      },
      methods: {
        randomIndex: function () {
          return Math.floor(Math.random() * this.items.length);
        },
        add: function () {
          this.items.splice(this.randomIndex(), 0, this.nextNum++);
        },
        remove: function () {
          this.items.splice(this.randomIndex(), 1);
        }
      }
    });
  </script>
</body>
上述例子我們可以看到<transition-group>中有用到tag來將原本預設的<span>替換成<ul>,這邊也可以試看看把tag拿掉看看~
接著我們在<style>加上v-move讓動畫看起來更順一點:
.list-move {
      transition: transform 1s;
    {
<transition>:
針對單一節點enter和leave各三種的class。
name:區分不同組的漸變樣式。
mode:漸變效果的順序(in-out;out-in)<transition-group>:
對應多個節點(例如列表list)
(<transition>有的我都有,但我還有以下的)tag:更改預設的spanv-move:定位改變的動畫
今天聊到的漸變需要搭配一些基本css知識,使用起來才會更得心應手喔!
這邊也附上官網的更多例子~