HTML5テクニカルノート
Vue.js + ES6: 動的に変更する要素にアニメーションを加える
- ID: FN1711001
- Technique: HTML5 / ECMAScript 2015
- Library: Vue.js 2.5.2
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■ボタンでテキストが動的に削除・追加される
加えられたり除かれたりする要素にアニメーションを与えるのが<transition>
ラッパーコンポーネントです(「単一要素/コンポーネントのトランジション」参照)。アニメーションさせたい要素を、つぎのように<transition>
コンポーネントで包みます。
<body>要素<transition> <p v-if="show">hello</p> </transition>
すると、CSSでアニメーションのための特別のクラスが自動的に使われます(「トランジションクラス」参照)。クラスv-enter
は、要素が加えられる前のスタイルを定めます。そして、v-enter-active
にtransition
やanimation
などのプロパティで、要素が加わるアニメーションを与えればよいのです。つぎの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')
);
<div id="demo">
<button v-on:click="show = !show">
Toggle
</button>
<transition>
<p v-if="show">hello</p>
</transition>
</div>
.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>
.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
属性です(「初期描画時のトランジション」参照)。デフォルトではenter
とleave
のトランジションクラスが使えます。
<body>要素<style>要素<transition appear name="todo-head"> <h1>todos</h1> </transition>
.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■テキストがフェードインしながら下りてくる
サンプル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は、トランジションクラスenter
とleave-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.