transitionとは?
Vue.jsでは、v-ifやv-showディレクティブで要素を表示・非表示する場合に、transitionタグによりアニメーションを付与することができます。
<template> <div> <button @click="isShow=!isShow">表示・非表示</button> <transition> <div v-if="isShow"> <p>表示されました</p> </div> </transition> </div> </template> <script> export default { data() { return { isShow: false } } } </script>
transitionタグを指定することにより以下の役割を持ったクラスが宣言されます。
クラス名 | 役割 |
---|---|
transition-enter-active | 表示中のスタイルを指定 |
transition-enter | 表示開始時のスタイルを指定 |
transition-enter-to | 表示終了時のスタイルを指定 |
transition-leave-active | 非表示中のスタイルを指定 |
transition-leave | 非表示開始時のスタイルを指定 |
transition-leave-to | 非表示終了時のスタイルを指定 |
上の例に対して以下のスタイルを定義したとします。
.transition-enter, .transition-leave-to { opacity: 0; } .transition-enter-active, .transition-leave-active { transition: opacity 1s; }
まず一つ目として、要素の表示開始時点と要素の非表示終了時点でのopacityを0に指定しています。 そして二つ目に、要素のopacityは表示・非表示処理で1秒かけて変化するよ、という指定をしています。
こうすることで表示側では1秒かけて浮かび上がるように表示され、非表示側では1秒かけてだんだんと消えていくようになります。
nameプロパティ
transitionタグにはnameプロパティを指定することができ、クラス名のtransition部分を変更することができます。次の例だと、show-enter-active のように変更されます。
<transition name="show"> <div v-if="isShow"> <!-- elements --> </div> </transition>
モーダルコンポーネントの作成
以下のような2つのモーダルコンポーネント(MyModal1, MyModal2)を作成しました。
2つのコンポーネントの違いは、アニメーションと表示制御になります。
アニメーション
MyModal1では、上記で説明したtransition-enter
, transition-leave-to
を利用してモーダルの表示・非表示時のアニメーションを定義しています。
それに対し、MyModal2ではtransition-enter-active
, transition-leave-active
のみ定義し、animation
を利用しています。
animation
に関する内容は割愛しますが、transition-enter
などを利用せずとも、表示(非表示)開始~表示(非表示)終了のアニメーションを設定することができます。
より複雑なアニメーションを設定する場合はanimation
を使います。
表示制御
MyModal1では、v-modelによって親から渡されたプロパティ値によって表示制御を行っています。
一方、MyModal2では親からの値に依存しない、自身のdata値によって表示制御を行っています。では親はどのようにして表示・非表示を行うことができるのでしょうか。
refプロパティ
ある特定の要素を参照する場合にはrefプロパティを使用します。
今回の場合、親は以下のようにMyModal2にrefプロパティを設定しています。
<my-modal2 ref="modal2" />
この要素を参照するには、this.$refs.modal2
とします。
今回の場合、親要素側のMyModal2の表示・非表示のメソッド、openModal2()
とcloseModal2()
は次のように定義しています。
methods: { openModal2() { this.$refs.modal2.open(); }, closeModal2() { this.$refs.modal2.close(); } }
見てわかるようにそれぞれMyModal2要素のopen()
とclose()
のメソッドを実行しています。これにより、結果的に親から子のdata値を書き換えています。
どちらの実装が良いのか?
一概にどちらが良いのか、明確な理由がないため私にはわかりません。
2つの実装の大きな違いは、親に依存するかどうかです。v-modelで実装した場合は親からの値に依存しますが、refプロパティでの実装の場合は子だけで完結しています。
どちらがいいのかはケースバイケースな気もするので状況に応じて使い分けてください。
- Vue.jsのおすすめ書籍はコチラ -
コメント