画面外のときは描画しないようにし、無限ローディング時の性能改善したときの備忘録。
vue-observe-visibilityを使って、画面内かを検知して表示を切り替えてみた。
インストール
まずはインストール。
$ npm install --save vue-observe-visibility # IEなどIntersection Observer APIに対応してないブラウザ用のpolyfill $ npm install --save intersection-observer
プラグインの作成
plugins/observe-visibility.tsを作成
// polyfillは最初に読み込む require('intersection-observer'); import Vue from "vue"; import VueObserveVisibility from "vue-observe-visibility"; Vue.use(VueObserveVisibility);
nuxt.config.tsに追加
作ったpluginを追加する
import { Configuration } from "@nuxt/types"; const config: Configuration = { plugins: [ { src: "~/plugins/observe-visibility", ssr: false }, ], }
使い方
使い方はこんな感じ。v-observe-visibilityディレクティブで設定する。
callbackには、画面内かの変数(isVisible)などを受け取るコールバックを指定onceには、初めて画面内になったら監視をやめるかどうかを指定intersectionには、検出に関する設定を指定。
<template> <section v-observe-visibility="{ callback: visibilityChanged, once: false, intersection: { rootMargin: '100px' } }" > <div v-if="isInview"><!-- 略 --></div> </section> </template> <script lang="ts"> import { Component, Vue } from "nuxt-property-decorator"; @Component export default class RankingMiniPanel extends Vue { private isInview: boolean = false; // **************************** // * Method // **************************** private visibilityChanged(isVisible, entry) { if (isVisible) this.isInview = true; } } </script>
コールバックは、マウント時を含めて、画面の中か外かが切り替わるときに呼ばれる。
なので、マウント時に画面外だと、isVisbleがfalseで呼ばれ、
画面内に入ると、isVisbleがtrueで呼ばれる。
コールバック内で、画面の中にあるかを変数(isInview)に保持しておき、
それによって描画する内容を変えるなどするといい感じになる。
画面内になったときにアニメーションさせるならvue-inviewがよいかも
今回は表示/非表示の切り替えのために検知したかったけど、
パラドックスのようなアニメーションをさせたい場合はvue-inviewがよさそう。
animate.cssと連動させて、いろいろできるっぽい。
以上!!