サイトトップ

Director Flash 書籍 業務内容 プロフィール

HTML5テクニカルノート

Vue.js + ES6: 動的に変更する要素にアニメーションを加える


Vue.jsで要素を動的に加えたり、除いたりするとき、アニメーションで変化させることができます。例を示しながら、基本的な操作についてご説明しましょう。さらに詳しくは、「Enter/Leaveとトランジション一覧」をお読みください 。

01 要素をフェードイン/フェードアウトさせる

まず用意しなければならないのは、要素を動的に加えたり除いたりするアプリケーションです。要素の表示・非表示はブール(論理)値のプロパティ(show)として、つぎのようにVue()コンストラクタに渡すオプションオブジェクトdataに定めます。なお、構文はECMAScript 2015(ECMAScript 6)にもとづき、const宣言アロー関数式を用いました。

<script>要素

const demo = new Vue({
	data: {
		show: true
	}
})
document.addEventListener('DOMContentLoaded', (event) =>
	demo.$mount('#demo')
);

<body>要素には、トグルボタン(<button>要素)とテキスト(<p>要素)を置きます(図001)。ボタンクリックのv-on:clickイベントでプロパティ(show)のブール値を反転し、テキストの要素に加えたv-ifディレクティブにより動的に追加・削除されます。

<body>要素

<div id="demo">
	<button v-on:click="show = !show">
		Toggle
	</button>
	<p v-if="show">hello</p>
</div>

図001■ボタンでテキストが動的に削除・追加される

図001

加えられたり除かれたりする要素にアニメーションを与えるのが<transition>ラッパーコンポーネントです(「単一要素/コンポーネントのトランジション」参照)。アニメーションさせたい要素を、つぎのように<transition>コンポーネントで包みます。

<body>要素

<transition>
	<p v-if="show">hello</p>
</transition>

すると、CSSでアニメーションのための特別のクラスが自動的に使われます(「トランジションクラス」参照)。クラスv-enterは、要素が加えられる前のスタイルを定めます。そして、v-enter-activetransitionanimationなどのプロパティで、要素が加わるアニメーションを与えればよいのです。つぎのCSSは、要素をフェードインで加えます。

<style>要素

.v-enter-active {
	transition: 3s ease-in-out;
}
.v-enter {
	opacity: 0;
}

要素をフェードアウトで除くには、また違ったクラスのCSSを定めます。アニメーションはv-leave-activeで、終わりの状態がv-leave-toです。つぎのCSSでは、transitionプロパティのアニメーション時間やタイミング関数を、フェードインとは少し変えてみました。

<style>要素

.v-leave-active {
	transition: 0.5s ease-in;
}
.v-enter, .v-leave-to {
	opacity: 0;
}

これでボタンをクリックするたびに、テキスト(<p>要素)がフェードアウトおよびフェードインするようになりました(コード001)。併せて、CodePenに以下のサンプル001を掲げてあります。

コード001■ボタンクリックで要素がフェードアウト・フェードインする

<script>要素

const demo = new Vue({
	data: {
		show: true
	}
})
document.addEventListener('DOMContentLoaded', (event) =>
	demo.$mount('#demo')
);

<body>要素

<div id="demo">
	<button v-on:click="show = !show">
		Toggle
	</button>
	<transition>
		<p v-if="show">hello</p>
	</transition>
</div>

<style>要素

.v-enter-active {
	transition: 3s ease-in-out;
}
.v-leave-active {
	transition: 0.5s ease-in;
}
.v-enter, .v-leave-to {
	opacity: 0;
}

サンプル001■Vue.js: Fade-out and fade-in animation

See the Pen Vue.js: Fade-out and fade-in animation by Fumio Nonaka (@FumioNonaka) on CodePen.

02 CSSプロパティanimationでアニメーションを与える

<transition>コンポーネントをいくつか加えて、それぞれに違ったアニメーションを定めたい場合には、つぎのようにname属性を与えます。

<body>要素

<transition name="bounce">
	<p v-if="show">hello</p>
</transition>

すると、トランジションクラスの接頭辞が「v」から、そのname属性値に変わります。これで、<transition>コンポーネントごとに異なるアニメーションのCSSが定められるでしょう。

<style>要素

.bounce-enter-active {
	transition: 3s ease-in-out;
}
.bounce-leave-active {
	transition: 0.5s ease-in;
}
.bounce-enter, .bounce-leave-to {
	opacity: 0;
}

<transition>コンポーネントには、トランジションクラスにtransitionだけでなくanimationプロパティで、より細かなアニメーションを加えることもできます。つぎのCSSは要素を除いたり加えたりするとき、水平にバウンドするようにアニメーションさせます。reverseは逆再生する設定です。

<style>要素

.bounce-enter-active {
	animation: bounce-in 0.5s;
}
.bounce-leave-active {
	animation: bounce-in 0.5s reverse;
}
@keyframes bounce-in {
	0% {
		transform: scale(0);
	}
	50% {
		transform: scale(1.5);
	}
	100% {
		transform: scale(1);
	}
}

これで、ボタンクリックして要素が削除・追加されるときのアニメーションは、水平にバウンドするような動きになりました。書き改めた<body>要素と<style>要素はつぎのコード002にまとめたとおりです。JavaScriptの記述は前掲コード001と変わっていません。以下のサンプル002をCodePenに掲げましたので、実際の動きはこちらでお確かめください。

コード002■要素が水平にバウンドするように削除・追加される

<body>要素

<div id="demo">
	<button v-on:click="show = !show">
		Toggle
	</button>
	<transition name="bounce">
		<p v-if="show">hello</p>
	</transition>
</div>

<style>要素

.bounce-enter-active {
	animation: bounce-in 0.5s;
}
.bounce-leave-active {
	animation: bounce-in 0.5s reverse;
}
@keyframes bounce-in {
	0% {
		transform: scale(0);
	}
	50% {
		transform: scale(1.5);
	}
	100% {
		transform: scale(1);
	}
}

サンプル002■Vue.js: Bounce out and in animation

See the Pen Vue.js: Bounce out and in animation by Fumio Nonaka (@FumioNonaka) on CodePen.

03 要素をはじめに描画するときアニメーションさせる

動的に追加・削除することなく、予め置いてある要素も、はじめに描画するときアニメーションさせることができます。このとき<transition>コンポーネントに加えるのがappear属性です(「初期描画時のトランジション」参照)。デフォルトではenterleaveのトランジションクラスが使えます。

<body>要素

<transition appear name="todo-head">
	<h1>todos</h1>
</transition>

<style>要素

.todo-head-enter-active {
	transition: 1s;
}
.todo-head-enter {
	opacity: 0;
	transform: translateY(-20px);
}

このコードを以下のサンプル003に加えると、タイトルのテキストがフェードインしながら下りてきます(図002)。サンプル003のコードの中身は、「Vue.jsの『TodoMVC の例』をECMAScript 6の構文に書き替える」および「Vue.js: TodoMVCをつくる」01〜05で解説しています。なお、書き替えたあとの動きについては、後掲サンプル004でお確かめください。

図002■テキストがフェードインしながら下りてくる

図002

サンプル003■Vue.js + ES6: TodoMVC

See the Pen Vue.js + ES6: TodoMVC by Fumio Nonaka (@FumioNonaka) on CodePen.

04 リストの要素をアニメーションさせる

アニメーションさせたい要素がv-forでつくられるリストのような場合には、<transition-group>コンポーネントを用います(「リストトランジション」参照)。コンポーネント<transition-group>は、<transition>と異なり、実際の要素を描画します。要素の種類を定めるのはtag属性です(デフォルトは<span>)。v-forでつくられるリストの親要素として加えます。なお、<transition-group>コンポーネントを使うとき、v-forが与えられた要素には必ずkey特別属性v-bindディレクティブ(省略記法:)でバインドしなければなりません(「Vue.js: TodoMVCをつくる 01 ー 項目の追加と削除および残り項目数表示」02「アプリケーションに定めた項目のデータをTodoリストに表示する」参照)。

<script>要素

<!--<ul class="todo-list">-->
<transition-group class="todo-list" name="todo-item" tag="ul">
	<li v-for="todo in filteredTodos"
		class="todo todo-item"
		:key="todo.id"

		>
		<div class="view">

		</div>

	</li>
<!--</ul>-->
</transition-group>

CSSは、トランジションクラスenterleave-toでアニメーションさせるプロパティの値を決めます。そして、transitionプロパティは<transition-group>コンポーネントに与えたクラス(todo-item)で定めてください。クラスの名前は任意で、とくに<transition-group>コンポーネントのname属性値と合わせなくて構いません。クラスleave-activeは、positionプロパティをabsoluteとします。

<style>要素

.todo-item {
	transition: 1s;
}
.todo-item-enter, .todo-item-leave-to {
	opacity: 0;
	transform: translateX(200px);
}
.todo-item-leave-active {
	position: absolute;
}

これで、リストの項目を加えたり除いたりすると、水平に移動しつつフェードイン・フェードアウトするようになります。コードは全体を示すとわずらわしくなりますので、つぎのサンプル004でお確かめください。内容については、「Vue.js: TodoMVCをつくる」01〜05および「Vue.jsの『TodoMVC の例』をECMAScript 6の構文に書き替える」で解説しています。

サンプル004■Vue.js + ES6: TodoMVC with animation

See the Pen Vue.js + ES6: TodoMVC with animation by Fumio Nonaka (@FumioNonaka) on CodePen.


作成者: 野中文雄
更新日: 2019年10月01日 サンプルをjsdo.itからCodePenに差し替え。
作成日: 2017年11月09日


Copyright © 2001-2017 Fumio Nonaka.  All rights reserved.