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

  • 18
    いいね
  • 0
    コメント

自己紹介

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