Vue.jsのTransitionでいい感じのアプリにする

More than 1 year has passed since last update.


自己紹介

icon_resize.png



今日話すこと


  • Transitionの話

  • Transitionを使うとアプリがいい感じになる(個人調べ)話





Transitionの基本



簡単な例

動的に動かしたい要素をtransitionコンポーネントで囲む

<transition name="fade">

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

v-if での要素の表示・非表示に連動してくれるようになる(v-show でもOK)



Transition時に付与されるクラス

image


  • それぞれのクラスにtransitionの設定を書いていく。



Transitionのクラス名の接頭辞について


  • transitionコンポーネントの name 属性に任意の文字を与えれば付与されるクラスの v- が置き換えられる

<transition name="fade">

なら

fade-enter fade-enter-active fade-enter-to



Transitionコンポーネントの何が嬉しいか


  • 今まで自分の手でタイミングよく付与していたクラスの制御を Vue 側に任せられる。

  • クラスの型が決まっているので自分たちはCSSのことだけ考えることができる。



Transitionのまとめ


  • transitionコンポーネントで囲む

  • 自動的に付与されるクラスに設定を書く

これだけ!らくちん!



ここからさき


  • transitionの事例などを紹介



モーダル

twish_tweet.gif



こんな感じの実装

https://github.com/nasum/twish/blob/master/src/renderer/components/TweetDialog.vue


<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の制限

twish_tweet_limit.gif



こんな感じの実装

https://github.com/nasum/twish/blob/master/src/renderer/components/TweetDialog.vue

<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;
}
},



タイムライン

twish_timeline.gif



こんな感じの実装

https://github.com/nasum/twish/blob/master/src/renderer/components/HomeTimeline.vue

<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(いいね)

twish_tweet_fav.gif



こんな実装

https://github.com/nasum/twish/blob/master/src/renderer/components/Tweet.vue

<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