シンプルブログ、ページ切り替わりのアニメーション

Vue.js

概要

DRFとVue.jsで、シンプルブログを作るシリーズの一つです。

ページが切り替わったときに、ちょっとしたアニメーションをつけていきます。

アニメーション

まずApp.vueを次のようにします。

<template>
    <div id="app">
        <Header/>
        <transition appear>
            <router-view/>
        </transition>
        <Footer/>
    </div>
</template>

<transition>で囲んだ部分が変化したときにアニメーションされるようになります。<router-view>部分を囲めば、ページ切り替わりの際のアニメーションをまとめて指定できます。

また、次のようなスタイル設定も追加しておきます。

    .v-enter-active {
        transition: opacity 1s;
    }

    .v-enter {
        opacity: 0;
    }

    .v-enter-to {
        opacity: 1;
    }

    .v-leave, .v-leave-active, .v-leave-to {
        opacity: 0;
    }

アニメーションさせたい要素には上のようなCSSのクラスが付与されるので、それに対して実際のアニメーションを指定しています。今回は1秒かけてじわじわ表示されるタイプ、フェードイン的な感じですね。

:keyを設定する

記事一覧→記事詳細はフェードインで表示されるようになりました。しかし次ページに移動した時のように、一覧→一覧はアニメーションされません。この場合は、要素に:keyを指定することで、そのkeyの値が変わった際にアニメーションするようになります。

PostList.vueを次のようにします。

 <main :key="getKey" class="container">

一番最初にあるmain要素に:key="getKey"をつけました。computed内、算出プロパティとして次のように定義します。

            getKey() {
                return `${this.postCurrentPageNumber} ${this.$route.query.keyword} ${this.$route.query.category}`
            },

ページ番号、キーワード、カテゴリを使って一意な文字列を作っています。これならばページ移動や検索の際にkeyの値が毎回変わりますので、毎回アニメーションされるようになります。

ちらつきをなくす

現在、ページ表示時に一瞬ちらつくというか、メインコンテンツの中身はAjaxで取得するまで空で高さがないため、フッターが上の方まできてしまいます。そしてAjaxでデータを読み込み終わったらメインコンテンツの高さが増えてフッターが画面外にいきます。これがちらつく原因です。

解決方法は幾つかあると思われますが、今回はメインコンテンツに最低限の高さを最初から持たせて置き、フッターがファーストビューの外に必ず配置されるようにしていきます。まずはApp.vueを変更します。

        <main>
            <transition appear>
                <router-view />
            </transition>
        </main>

main要素で囲むようにしました。別にmainじゃなくてもdivとかでもいいんですが、mainタグを使うのが素直に思います。そして、次のようなスタイル設定をします。

    main {
        min-height: calc(100vh - 290px);
    }

100vhは画面の高さ、ファーストビューの高さです。最低限の高さとして、これをそのまま指定しても良いのですが、それだとフッターが下に行きすぎちゃって、場合によっては空白が目立ちます。なので、ヘッダー部分の高さやヘッダー下、フッター上のマージンなどを加味して、290pxを引いて分の高さにしています。これだと、ファーストビューがのすぐ後にぴったりフッターが配置されます。

PostList.vueも編集します。ここはmain要素を既に使っていましたが、mainはApp.vue側に書いたので、仕方なくdivあたりで囲みましょう。

<main :key="getKey" class="container">
↓
<div :key="getKey" class="container">

Relation Posts

Comment

記事にコメントする

まだコメントはありません。