Vue.jsでtransition(トランジション)を使ってアニメーションする方法について書いています。
transitionを使用することで、v-showやv-ifなどの動的に表示が変わる箇所で、フワッと出したりスライドさせたりするアニメーションをつけることが可能です。
Vue.js 3.2.31 Composition API
Vue CLI 5.0.4
公式サイトのこちらの内容になります。
transitionでアニメーションをつけるには?
transitionでアニメーションをつけるには、transitionタグを使用します。
下記のようにVueのタグの箇所で、v-ifやv-showの動的に表示が変わる箇所を、transitionタグを使用して囲みます。
<transition>
<div v-show="isShowText">Hello, World!!</div>
</transition>
こうすることで、要素が表示されたり消える時に、対象のタグに対してクラスが付加されます。
付加されるクラスは下記の6つです。
付加されるクラス | 付加されるタイミング |
---|---|
v-enter-from | 対象の要素が表示される時に付加されて、要素が挿入された1フレーム後に削除されます。 |
v-enter-active | 対象の要素が挿入される前に追加されて、アニメーションが終了すると削除されます。 |
v-enter-to | 対象の要素が挿入された1フレーム後に付加されて、アニメーションが終了すると削除されます。 |
v-leave-from | 対象の要素が非表示になる時に付加されて、要素が非表示になる1フレーム後に削除されます。 |
v-leave-active | 対象の要素が非表示になる前に追加されて、非表示にするアニメーションが終了すると削除されます。 |
v-leave-to | 対象の要素が非表示になる1フレーム後に付加されて、アニメーションが終了すると削除されます。 |
上記のように6つのクラスが、それぞれのタイミングで対象要素に付加されます。
要素が表示されるときに一瞬だけv-enter-fromが付加されて、v-enter-active・v-enter-toがアニメーションが終わるまで付加されます。
また、非表示の方では、非表示になるときに一瞬だけv-leave-fromが付加されて、v-leave-active・v-leave-toがアニメーションが終わるまで付加されます。
実際に使用すると、下記のようにclassが付加されていることが確認できます。
アニメーションの時間を5秒くらいにして、わかりやすくしました。
「メッセージを表示する」ボタンで、メッセージを表示したり、非表示にしたりを切り替えます。
最初にボタンを押すと、メッセージを表示するためv-enter-active・v-enter-toがついています。
次にボタンを押すと、メッセージを非表示にするためv-leave-active・v-leave-toがつきました。
v-enter-from・v-leave-fromがついていることが確認できませんが、一瞬なのですぐに消えているのだろうと思います。
それでは、次にこちらのサンプルコードを次項で見てみましょう。
transitionを使用して、フワっと表示する
「メッセージを表示する」ボタンを押すと、テキストの表示・非表示を切り替えるというコンポーネントです。
<template>
<div class="m-5">
<transition>
<div v-show="isShowText">Hello, World!!</div>
</transition>
<button @click="showText" class="rounded border-2 bg-red-500 border-red-300 text-white px-2 py-1 mt-2">
メッセージを表示する
</button>
</div>
</template>
<script>
import { ref } from "vue"
export default({
setup() {
const isShowText = ref(false)
const showText = () => {
if (isShowText.value) {
isShowText.value = false
} else {
isShowText.value = true
}
}
return {
isShowText,
showText
}
}
})
</script>
<style>
.v-enter-active, .v-leave-active {
transition: opacity 1.3s ease;
}
.v-enter-from, .v-leave-to {
opacity: 0;
}
</style>
タグの解説
タグの箇所を確認すると、下記のようにtransitionを使用しているところがあります。
<transition>
<div v-show="isShowText">Hello, World!!</div>
</transition>
transition配下の表示・非表示を切り替えることで、対象にクラスが付加されます。
transitionタグの下にはbuttonタグを用意しています。
このボタンをクリックすることで、isShowText変数の論理値を切り替えて、表示・非表示を変えるようにしています。
スクリプトの解説
次にスクリプトの箇所を確認します。
最初にimportを使用して、Vue.jsのrefを読み込んでいます。
このrefを使用することで、リアクティブな論理値を作成して、テキストエリアの表示を切り替えます。
setup関数を確認すると、isShowTextという変数をrefで作成しています。
const isShowText = ref(false)
その次に、showText関数を作成しています。
このshowText関数はボタンが押された時に実行される関数です。
const showText = () => {
if (isShowText.value) {
isShowText.value = false
} else {
isShowText.value = true
}
}
isShowTextがtrueだったらfalseにして、falseだったらtrueに設定するようにしています。
こうすることで、表示・非表示がボタンを押した時に切り替わるようになります。
最後にreturnで、関数と変数を返して、画面で使用できるようにしています。
スタイルの解説
下記のように、transitionで付加されるクラスに対して、CSSを適用しています。
.v-enter-active, .v-leave-active {
transition: opacity 1.3s ease;
}
.v-enter-from, .v-leave-to {
opacity: 0;
}
v-enter-fromクラスが付加されて、次に付加されるv-enter-activeクラスでtransitionのCSSプロパティを使って、少しずつ(1.3秒で)opacityの状態を変化させてアニメーションします。
逆にleaveの方はv-leave-activeクラスが付加された後に、v-leave-toクラスが付加されてopacityが0になるまでアニメーションします。
動作確認をする
5秒にしていたのを、1.3秒にしているので先ほどのアニメーションより早くなりました。
transisionでスライドしたい
transisionで要素をスライドして、左から右に表示して、消すときに右から左に動かします。
先ほどのサンプルのスタイルの箇所を修正すると可能です。
<style>
.v-enter-to {
transition: transform 1.3s ease-out;
transform: translateX(0px);
}
.v-enter-from {
transform: translateX(-100px);
}
.v-leave-to {
transition: transform 1.3s ease-out;
transform: translateX(-100px);
}
.v-leave-from {
transform: translateX(0px);
}
</style>
スタイルを上記のように修正しました。
transformプロパティを使用して、動かすようにしてみました。
v-enter-fromが最初に付加されて、左の-100pxの位置に設定されて、v-enter-toの0pxの位置まで動きます。
leaveの方にも同様のスタイルをつけて、逆に右から左に動かして消すようにしてみました。
動作確認をする
実際にブラウザで確認してみると、下記のように左から右にメッセージが流れてきます。
その後に、もう一度ボタンを押すと、右から左に消えていきます。
transitionで使用するクラス名を変えたい
transitionタグを複数使用したい場合などで、アニメーションを分けたい時などにクラスの名前が被ると困ることになります。
name属性を使用することで、クラス名の「v
」の部分の名前を変えることが可能です。
下記がサンプルコードです。
先ほどテキストだったのを今回は画像にして試してみました。
<template>
<div class="m-5">
<button @click="showImages" class="rounded border-2 bg-red-500 border-red-300 text-white px-2 py-1 mt-2">
画像を表示する
</button>
<transition name="cat">
<img v-show="isShowImage" width="250" src="../assets/sleep_animal_cat.png" />
</transition>
<transition name="penguin">
<img v-show="isShowImage" width="250" src="../assets/hiyake_penguin.png" />
</transition>
</div>
</template>
<script>
import { ref } from "vue"
export default({
setup() {
const isShowImage = ref(false)
const showImages = () => {
if (isShowImage.value) {
isShowImage.value = false
} else {
isShowImage.value = true
}
}
return {
isShowImage,
showImages
}
}
})
</script>
<style>
.cat-enter-to {
transition: transform 1.3s ease-out;
transform: translateX(0px);
}
.cat-enter-from {
transform: translateX(-250px);
}
.cat-leave-to {
transition: transform 1.3s ease-out;
transform: translateX(-250px);
}
.cat-leave-from {
transform: translateX(0px);
}
.penguin-enter-active, .penguin-leave-active {
transition: opacity 1.3s ease;
}
.penguin-enter-from, .penguin-leave-to {
opacity: 0;
}
</style>
解説
タグの箇所をみてみると、transitionが2つになっています。
<transition name="cat">
<img v-show="isShowImage" width="250" src="../assets/sleep_animal_cat.png" />
</transition>
<transition name="penguin">
<img v-show="isShowImage" width="250" src="../assets/hiyake_penguin.png" />
</transition>
name属性を使用することで、それぞれの名前のクラスが付加されるようになります。
クラス名の先頭の「v」がnameに書いた属性の値になります。
そのため、catの箇所はcat-enter-to,cat-enter-from,cat-enter-activeのような形です。
leaveも同じように要素が消える際に付加されます。
これを利用して、2つのtransitionに別々のname属性を設定しました。
スクリプトの箇所は、前項と同様の処理をしているので割愛します。
変数名と表示・非表示を切り替える関数の名前を画像なので、変えた形です。
スタイルの箇所を確認します。
それぞれname属性を付けてあげたので、それぞれのクラスが付加されるようになりました。
猫の画像にcat-enter-xxx, cat-leave-xxxが付加されます。
同様にして、ペンギンの画像にpenguin-enter-xxx, pengin-leave-xxxが付加されます。
猫のクラスの方にスライドのCSSを適用して、ペンギンにフワッと表示されるCSSを適用しました。
動作を確認する
実際の動作を確認すると、下記のようにそれぞれ適用されたクラスのアニメーションが動くことが確認できました!
コメント