もっと実践的にTransition

2020/01/23

yumemi.vue #5

jiyuujin

  • Vue/Nuxt/PHP/Scala/Java/Swift
  • v-kansai/kansai.ts/..
  • Web猫ブログ (webneko.dev)

現在のお仕事は

  • Vue CLI ベースのMPA構成を構築、コンポーネント単位でリプレースを進めてます
  • Next.js + AppSync のサーバレス環境で、新しいしごと情報を管理する両サイトの制作を進めてます
    • デモサイト (Amplify CLI/SDKを使って)
    • 本番サイト (apollo-clientライブラリを使って)

VueをMPA環境で使..

Transitionを気軽に使う

Transitionについて

バリバリ使っている人🙋‍♀️

導入方法について

入れたい要素をタグで囲う

<transition name="slide-fade">
    <div>
        <!--  入れたい要素  -->
    </div>
</transition>

表示のタイミングで

  • enter のスタイルを定義
  • <transition name="slide"></transition> で付けた名前を enter のスタイルに適用
    • slide-fade-enter という名前で指定

非表示のタイミングで

  • leave のスタイルを定義
  • <transition name="slide"></transition> で付けた名前を leave のスタイルに適用
    • slide-fade-leave という名前で指定

いずれも要素を挿入する前に発火

活性中のスタイルも定義できる

-activeというプレフィックスを付ける

  • slide-fade-enter-active という名前で指定
  • slide-fade-leave-active という名前で指定

終了時のスタイルも定義できる

(Vue2.1.8以降)

-toというプレフィックスを付ける

  • slide-fade-enter-to という名前で指定
  • slide-fade-leave-to という名前で指定

DEMO

実際にこうやって使った

  1. リスト内の店舗を選択する
  2. 開始日、終了日を指定する

リスト内の店舗を選択する

主な技術スタック

  • 実は総じて変わったことをしていないという😅
  • 事前に全店舗情報をサーバサイドから取得
  • vuexを使わずローカルstateで選択店舗を管理
  • お気に入りは指定のcookieを利用

どの部分で Transition を使っているでしょうか?

選択した時、選択を外した時

name="selected" を付けた上で

.selected-enter {
  transform: translateX(5px);
  opacity: 0;
}

.selected-enter-active,
.selected-leave-active {
  transition: all 0.15s ease-out;
}

.selected-enter-to {
  transform: translateX(0px);
  opacity: 1;
}

.selected-leave-to {
  transform: translateX(5px);
  opacity: 0;
}

しかしここで問題点が

一つも選択してない状態で新たに選択すると?

上手くTransitionが挙動しない

とある時だけ遅れて表示される🤔

あくまで理想としては均一のTransitionに揃えたい

表示のタイミングを揃えよう

表示のタイミングを一律ずらした

import Vue from 'vue'
export default Vue.extend({
    methods: {
        beforeEnter(el) {
            el.style.transitionDelay = 100 * parseInt(el.dataset.index, 10) + 'ms'
        },
        afterLeave(el) {
            el.style.transitionDelay = ''
            if (this.selectedIds.length !== 0) {
                this.isEmpty = false
            } else {
                this.isEmpty = true
            }
        }
    }
})

フックを使って解決できた!

現在のTransitionが終わってから

新規のTransitionに移行させたい

mode属性を追加

<transition name="slide" mode="out-in">
    <div></div>
</transition>

完全に分離させてより確実に

スタイル調整が難しいなら

スクリプトで書いちゃえば良い😇

主な技術スタック

  • Dateインスタンスに加えdayjsも日付処理に利用
  • vuexを使わずローカルstateで開始日、終了日を管理
  • RangePickerのみならずSinglePickerにも対応
  • 即設定できるようにショートカットボタンも準備

どの部分で Transition を使っているでしょうか?

ボタンクリックのタイミング

name="picker" を付けた上で

.picker-enter-active {
    transition: all .2s ease;
}

.picker-leave-active {
    transition: all .1s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}

.picker-enter {
    transform: translateX(10px);
    opacity: 0;
}

.picker-leave-to {
    transform: translateX(10px);
    opacity: 0;
}

右から左へと浮き出るようなTransitionを実現

最後にまとめ

  • 基本的に enter と leave を使おう、活性開始・活性中・活性終了の各ステージごとに分けて考える
  • 実際にTransitionが入っていることに気付きにくいような、とても痒いところにも充分手が届く
  • 無理にスタイルで頑張らなくて良くて、スクリプトでも微調整は充分可能なので頑張ってみる

ちなみに今回ご紹介の例いずれもMPA環境でリリース済み

npm i @nekohack/j-stylebook

Thank you..🙇‍♀️

もっと実践的にTransition

By jiyuujin

もっと実践的にTransition

Yumemi.vue #5 で登壇しました。

  • 1,079