Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

【vue】vue-routerでviewごとに異なるcssトランジションを設定したい

More than 3 years have passed since last update.

概要

この記事は モバイルファクトリー Advent Calendar 2017 17日目の記事です。

16日目の記事は @tsukumaru さんの go-staticmapsの地図にアイコンとして任意の画像を表示したい でした。

先日vueのcssアニメーションについて触れる機会があったので、17日目の本記事ではタイトルのとおりvueのcssトランジションまわりについてご紹介します。

vueでトランジション

vueでv-ifv-showによってコンポーネントの表示・非表示が切り替わる際にトランジションをさせたい場合は、そのコンポーネントを<transition>で囲うことで実現できます。
transitionコンポーネントのname属性に基づいたcssアニメーションが再生され、このときcssクラス名は*-enter-to,*-enterといった特定のクラス名でなければいけません。

参考:Enter/Leave とトランジション一覧 - トランジションクラス

<div id="demo">
  <button v-on:click="show = !show">
    Toggle
  </button>
  <transition name="fade">
    <p v-if="show">hello</p>
  </transition>
</div>
new Vue({
  el: '#demo',
  data: {
    show: true
  }
})
.fade-enter-active, .fade-leave-active {
  transition: opacity .5s
}
.fade-enter, .fade-leave-to {
  opacity: 0
}

vue-routerでviewを変更した際にトランジションさせる

<router-view>内でレンダリングされるviewが変更された際にトランジションを設定する場合も同様に<transition>を用いることで実現することができます。

<transition name="fade">
  <router-view></router-view>
</transition>

viewごとに異なるトランジションを設定する

先ほどの例だとrouter-viewを通して表示されるすべてのviewに対してfadeトランジションを行いますが、場合によってはviewごとに異なるトランジションを設定したい場合もあると思います。

トランジションの仕組み

Enter/Leave とトランジション一覧 - 単一要素-コンポーネントのトランジションに記述がありますが、transitionコンポーネントにラップされたコンポーネントに対してCSS トランジションのクラスを追加・削除を行うことでトランジションさせるような仕組みになっています。
なので、実際先ほどの例でhogeコンポーネントが描画されトランジションをしている間には以下のようなクラスが付与されています。

hogeコンポーネントが描画されたとき
<hoge class="fade-enter-active fade-enter-to"></hoge>

コンポーネントごとにCSSトランジションを記述する

つまり、描画されているコンポーネントのルートノードに対してCSSクラスが追加されるので、各コンポーネントごとにCSSトランジションを設定すれば各viewごとに異なるトランジションをさせることができます。

ただ単に設定しただけでは*-enter-active等のクラス名が重複してしまうので、各コンポーネントのスタイルをscoped cssにしてあげます。

hoge.vue
<template>
  <p>HOGE</p>
</template>

<style scoped>
.fade-enter-active {
  transition: all 1s 0s ease;
}
.fade-enter {
  opacity: 0;
}
</style>
fuga.vue
<template>
  <p>HUGA</p>
</template>

<style scoped>
.fade-enter-active {
  transition: all 1s 0s ease;
}
.fade-enter {
  transform: translate(-100px, 0);
}
</style>
App.vue
<template>
  <div id="app">
    <transition name="fade" appear>
      <router-view></router-view>
    </transition>
    <div>
      <router-link to="/hoge" >to hoge</router-link>
      <router-link to="/fuga" >to fuga</router-link>
    </div>
  </div>
</template>

vue.gif

viewごとに異なるトランジションを設定できました。

まとめ

scoped cssを利用することでviewごとにトランジションを設定することが出来ます。同様にcssアニメーションも設定することができます。

vueのトランジションに関するドキュメントを見る限り、JSフックやリストトランジション等できることは様々あるようなので、それらに触れた際にはまたまとめておきたいと考えてます。

明日の担当は @akihiro_0228 さんです。よろしくお願いします。

tenmihi
mfac
実際に人を動かすことを特徴とした位置情報連動型ゲーム及びサービスを開発しています。
http://www.mobilefactory.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away