基礎からメモ: Vue.js CH6-p210 SVGのトランジションとトランジションフック

SVGトランジション

SVGマークアップされた要素にトランジション。 図形が入れ替わる。

<div id="app">
  <button v-on:click="toggle=!toggle">切り替え</button>
  <svg xmlns="http://www.w3.org/2000/svg" version="1.1">
    <!-- SVGのパーツにトランジションを適用する -->
    <transition>
      <my-circle v-bind:fill="fill" v-bind:key="fill"></my-circle>
    </transition>
  </svg>
</div>
// SVGトランジション

Vue.component('my-circle', {
  template: '<circle cx="80" cy="75" r="50" v-bind:fill="fill"/>',
  props: { fill: String }
})

var app = new Vue({
  el: '#app',
  data: {
    toggle: false
  },
  computed: {
    fill: function() {
      return this.toggle ? 'lightpink' : 'skyblue'
    }
  }
});

ボタンクリックすると水色の円とピンクの円が入れ替わる。

/* トランジション用スタイル */
.v-enter-active, .v-leave-active {
  transition: all 1s;
}
.v-leave-active {
  position: absolute;
}
.v-enter, .v-leave-to {
  opacity: 0;
  transform: translateX(-20px);
}

トランジションフック

トランジションの動作の際のどこかのタイミングを捉えて操作するトランジションフック

v-onで指定するイベント名にトランジションフック名を指定し、対応するハンドラを定義しておく。

<div id="app">
  <p><button v-on:click="show=!show">切り替え</button></p>
  <transition v-on:enter="enter" v-on:after-enter="afterEnter">
    <div v-if="show">Example</div>
  </transition>
</div>

ボタンをクリックすると'Example'の文字列がじわっと消えたり現れたりするが、v-ifを使ってshowプロパティの真偽に対応させているので、消えるときはDOMが無くなる。enterフックは.v-enterクラスが付与されDOMに要素が追加されたときに作用する。after-enterトランジションが終わるか、enterがdone()した後に作用。

// トランジションフック

var app = new Vue({
  el: '#app',
  data: {
    show: true
  },
  methods: {
    enter: function(el, done) {
      console.log('enter')
      // 1秒後にenterを終了してafter-enterに遷移
      setTimeout(done, 1000) 
    },
    afterEnter: function(el) {
      console.log('afterEnter')
    }
  }
});
/* トランジション用スタイル */
.v-enter-active, .v-leave-active {
  transition: all 1s;
}
.v-leave-active {
  position: absolute;
}
.v-enter, .v-leave-to {
  opacity: 0;
  transform: translateX(-20px);
}

使用できるトランジションフック

Enter系フック タイミング
before-enter DOMに要素が追加される前
enter DOMに要素が追加されて.v-enterが付与された後
after-enter トランジションが終わるか、enterdone()した後
enter-cancelled Enterフェーズが途中でキャンセルしたとき
Leave系フック タイミング
before-leave クラスが追加される前
leave .v-leaveクラスが追加された後
after-leave DOMから要素が削除された後、またはleavedone()した後
leave-cancelled Leaveフェーズが途中でキャンセルされたとき

cancelledが付いているフックは、トランジション中に連続クリックなどで動作中のトランジションが途中キャンセルされた場合に呼び出されるもの。

各フックには第一引数にトランジションが行われている要素が渡される。また、enterleaveフックには第二引数として、トランジションの終了を明示的にするためのコールバックdoneを受け取る。

enterleaveフックをハンドルしている場合、done()を実行しないと次のフックに遷移しないが、done()実行後すぐにトランジションを終了し次のフックに遷移する。CSSトランジションが終わる前に次のフックに遷移させたくない場合は、setTimeoutメソッドなどでCSSトランジションの終了後にdone()が実行されるように調整する。

Vue.js側で通常のCSS操作を行わないようにする

すべてをJavaScriptで制御したい場合、トランジションクラスについての通常のCSS操作を抑制するために、次のようにv-bind:css="false"を指定する。

<transition v-bind:css="false" v-on:before-enter="beforeEnter">
  <div v-if="show">Example</div>
</transition>