<transition>
<transition>は、ひとつの要素しか入れる事ができない。
切り替えを書き込む時は、v-ifを用いること。
v-showは、display:none;で画面上非表示になっているだけなので、ソースから完全に消えるv-ifを用いる。
テンプレートの切り替えを行う部分を<transition>で囲む。
name属性に何もいれない場合、name=”v”がデフォルトで付与される。このname属性で設定した値は、styleでclass名として使用することとなる。
<template> <div class="main"> <button @click="fade = !fade">切替</button> <transition name="animation"> <p v-if="fade">こんにちは</p> </transition> </div> </template> <script> export default { data() { return { fade: true }; } }; </script>
styleタグの中に、6つのclassを追加する。
この6つのクラスは、Vueが用意しているアニメーションクラス。animationは、上記HTML内でname属性に付けた値になる。
<style scoped> .animation-enter { opacity: 0; } .animation-enter-active { transition: opacity 3s; } .animation-enter-to { opacity: 1; } .animation-leave { opacity: 1; } .animation-leave-active { transition: opacity 3s; } .animation-leave-to { opacity: 0; } </style>
.name属性名-enter => 出現した最初の状態
.name属性名-enter-active => 出現するときのトランジション効果
.name属性名-enter-to => 出現の最後の状態
.name属性名-leave => 消える最初の状態
.name属性名-leave-active => 消えるときのトランジション効果
.name属性名-leave-to => 消える最後の状態
トランジションクラスの挙動
Vueは自動的にStyleで定義したクラスをHTML要素の中に自動的に適用させていく。
最初に、[name]-enterと[name]-enter-activeが追加される。
ブラウザーの表示1フレーム後に[name]-enterが削除され[name]-enter-toが追加される。
DOMからアニメーションが終わったことを受け取り、[name]-enter-toと[name]-enter-activeを削除する。
[name]-leave,-leave-active,-leave-toもenterと同じ動きをする。
<style>animationとtransitionを両方使う時
animationとtransitionを両方使用する時、どちらのアニメーションタイミングを適用するか要素にtype属性を用いる事で設定ができる。
例えば、下記のようにanimationとtransitionが混在している場合、animationの0.5sで挙動を揃えたいとすると、
.slide-enter-active { animation: slide-in 0.5s; transition: opacity 5s ; }
<transition>タグの中にtype属性を追記して優先させるプロパティを記載する。
<transition name="slide" type="transition">
最初の描画にトランジションを適用する
リロードした時など、読み込み時の最初の挙動にトランジションを適用したい時、<transition>にappear属性を付与する。
<transition name="slide" appear>
カスタムトランジションクラス
<transition>タグ内にVue独自のclass名を属性に使う事で、class名を上書きする事ができる。
VueClass=””で要素を空にすることもできる。
CSSライブラリ等を利用する際に有効。
<transition enter-class="" enter-active-class="animated bounce" enter-to-class="" leave-class="" leave-active-class="animated zoomIn" leave-to-class="" >
カスタムにする際は、常に付与されるclassである、enter-active,leave-activeを上書きするとよい。
要素を切り替える
複数の要素を切り替える時(但し、表示される要素はひとつだけ)、v-ifを使って動作の遷移をさせる。
<template> <div class="main"> <button @click="fade = !fade">切替</button> <transition name="animation"> <p v-if="fade">こんにちは</p> <div v-else>さようなら</div> </transition> </div> </template> <script> export default { data() { return { fade: true }; } }; </script> <style scoped> .animation-enter { opacity: 0; } .animation-enter-active { transition: opacity 3s; } .animation-enter-to { opacity: 1; } .animation-leave { opacity: 1; } .animation-leave-active { transition: opacity 3s; } .animation-leave-to { opacity: 0; } </style>
v-elseのところでdivを用いている理由は、切り替え前と切り替え後のタグが同じ<p>を用いた場合、Vueが自動的に要素の中身だけを置き換えてしまう。そのため、トランジションが効かなくなる。
同じタグを使う場合は、key属性を付与してそれぞれのタグが違う意味であることを認識させる。
<p v-if="fade" key="hello">こんにちは</p> <p v-else key="bye">さようなら</p>
複数の要素を切り替える時、現れる要素が完全に表れてから次の要素を出したいといった時、mode属性を使用する。
mode属性には[out-in]と[in-out]の値が用意されている。
<transition name="animation" mode="out-in">
JavaScriptでアニメーションを設定する
<transition>には8個のJavaScriptフックを持っている。
@before-enter => 出現前
@enter => 出現時
@after-enter => 出現後
@enter-cancelled => アニメーションがキャンセルになったとき
@before-leave => 消える前
@leave => 消去時
@after-leave => 消えた後
@leave-cancelled => アニメーションがキャンセルになったとき。v-showに対してのみ実行される。
<transition mode="out-in" @before-enter="beforeEnter" @enter="enter" @after-enter="afterEnter" @enter-cancelled="enterCancelled" @before-leave="beforeLeave" @leave="leave" @after-leave="afterLeave" @leave-cancelled="leaveCancelled" >
それぞれmethodsを作成する。
引数にはel(element)が入る。enterとleaveのみ引数にelとdoneが入る。
methods:{ beforeEnter(el){}, enter(el,done){}, afterEnter(el){}, enterCancelled(el){}, beforeLeave(el){}, leave(el,done){}, afterLeave(el){}, leaveCancelled(el){} }
アニメーションをセットした例↓
methods: { beforeEnter(el) { el.style.transform = "scale(0)"; }, enter(el, done) { let scale = 0; const interval = setInterval(() => { el.style.transform = `scale(${scale})`; scale += 0.1; if (scale > 1) { clearInterval(interval); done(); } }, 100); }, afterEnter() {}, enterCancelled() {}, beforeLeave() {}, leave(el, done) { let scale = 1; const interval = setInterval(() => { el.style.transform = `scale(${scale})`; scale -= 0.1; if (scale < 0) { clearInterval(interval); done(); } }, 100); }, afterLeave() {}, leaveCancelled() {} }
doneは非同期処理に使われる。
cssのアニメーションと組み合わせて使用するときは、doneはなくて良い。(ない方が良い)
doneがあると、cssアニメーションが終了する前にdoneが出現したタイミングでアニメーションが終わってしまう。
<メモ>
JSでアニメーションを実装し、cssを使わない時、:css=”false”でVueにcssを使用しない旨を伝える事ができる。
属性を持たせる事で読み込みが速くなる。
<transition :css="false">
< transition-group>
transition-groupを使う時には、key属性をそれぞれに付与しなければならない。
<ul> <transition-group name="animation"> <li v-for="(number,index) in numbers" @click="remove(index)" v-bind:key="index">{{ number }}</li> </transition-group> </ul>
transition と transition-group の違い
- 複数の要素をとることができる
- 必ずkey属性を付ける必要がある
- <span>タグになる
<span>をtag属性で変更する事も可能。
※transitionは何者にもならない
<transition-group name="animation" tag="div">
- transitionにあったmode属性がない。
- [name]-moveクラスが存在する。
[name]-moveクラス
要素に追加や削除があった時に付与するアニメーションクラス。
Vueが自動的にtransformで動かしてくれる。
切換をもっとなめらかにしたいときに設定。
[name]-moveにいれるcssは固定。秒数を自由に設定する事ができる。
transition: transform 1s;
青マーカの部分は固定。
.animation-move{ transition: transform 1s; }