自己紹介
- nasum
- github: https://github.com/nasum
- twitter: https://twitter.com/tomato360
- 主にRubyとかRailsで仕事しています
- 趣味でVue.jsを使っています
今日話すこと
- Transitionの話
- Transitionを使うとアプリがいい感じになる(個人調べ)話
- 自分で作っているTwitterクライアントをベースに紹介
- https://github.com/nasum/twish
Transitionの基本
- 詳しくは公式ガイドを見るのが一番早い
- https://jp.vuejs.org/v2/guide/transitions.html
- 今日お話するのはCSS transition を使った例
簡単な例
動的に動かしたい要素をtransitionコンポーネントで囲む
<transition name="fade">
<p v-if="show">hello</p>
</transition>
v-if
での要素の表示・非表示に連動してくれるようになる(v-show
でもOK)
Transition時に付与されるクラス
- 詳しくは(以下略
- https://jp.vuejs.org/v2/guide/transitions.html#トランジションクラス
- 要素が表示されるとき
-
v-enter
→v-enter-active
→v-enter-to
-
- 要素が非表示されるとき
-
v-leave
→v-leave-active
→v-leave-to
-
- それぞれのクラスにtransitionの設定を書いていく。
Transitionのクラス名の接頭辞について
- transitionコンポーネントの
name
属性に任意の文字を与えれば付与されるクラスのv-
が置き換えられる
例
<transition name="fade">
なら
fade-enter
fade-enter-active
fade-enter-to
Transitionコンポーネントの何が嬉しいか
- 今まで自分の手でタイミングよく付与していたクラスの制御を
Vue
側に任せられる。 - クラスの型が決まっているので自分たちはCSSのことだけ考えることができる。
Transitionのまとめ
- transitionコンポーネントで囲む
- 自動的に付与されるクラスに設定を書く
これだけ!らくちん!
ここからさき
- transitionの事例などを紹介
モーダル
こんな感じの実装
<transition name="fade" v-on:enter="enter">
<div class="grass-pane" v-show="$store.state.TweetDialog.open" @click="clickGrassPane">
...modalのあれこれ
</div>
</transition>
methods: {
clickGrassPane: function () {
//クローズの処理。ストアのopenを変えている
this.$store.dispatch('closeTweetDialog');
},
}
/* 実はガイドに書いてあるのがそのまま */
.dialog-enter-active, .dialog-leave-active {
transition: opacity .5s
}
.dialog-enter, .dialog-leave-to {
opacity: 0
}
v-show
を検知してtransitionしてくれる。動きはcssに書くだけ。
Tweetの制限
こんな感じの実装
<transition>
<div v-bind:class="{ ok: textState, ng: !textState }">
{{ count }}
<transition mode="out-in">
<span class="icon" v-bind:class="{ 'icon-check': textState, 'icon-cancel': !textState }" v-bind:key="textState"></span>
</transition>
</div>
</transition>
computed: {
textState: function (e) {
if (this.count <= 150) {
return true;
} else {
return false;
}
},
count: function () {
return this.$store.state.TweetDialog.message.length;
}
},
タイムライン
こんな感じの実装
<transition-group name="list" tag="div">
<tweet :status="status" v-for="status in sliceTweets" :key="status.id" @click='showDetail(status)'></tweet>
</transition-group>
computed: {
sliceTweets: function(){
return this.$store.state.Tweet.displayTweets.slice(0, this.displayCount);
}
},
.list-enter-active, .list-leave-active {
transition: all 1s;
}
.list-enter, .list-leave-to {
opacity: 0;
transform: translateY(-30px);
}
Fav(いいね)
こんな実装
<transition name="fav" mode="out-in">
<span class="icon icon-heart reaction" @click="like" @click.stop v-if='status.favorited' key='onFav'></span>
<span class="icon icon-heart-empty reaction" @click="like" @click.stop v-if='!status.favorited' key='offFav'></span>
</transition>
methods: {
like: function () {
if (this.status.favorited) {
this.$store.dispatch('destroyLike', { status: this.status });
} else {
this.$store.dispatch('createLike', { status: this.status });
}
},
}
.fav-enter-active, .fav-leave-active {
transition: all .3s ease;
}
.fav-enter, .fav-leave-to {
opacity: 0;
transform: translateY(30px);
}
まとめ
- transitionはCSSのことだけを考えればいいので楽
- アプリケーションがより魅力的になる!
- CSSアニメーションとかの難しさに直面しても負けないで!
- 僕はちょっと怖気づいているw