vue-intersectがシンプルで便利だったので、使い方をメモ。
こちらを参考にインストール
NPM
npm install vue-intersect --save
Yarn
yarn add vue-intersect
使い方
使いたいVueファイルに、importして、@enter=で表示した時に実行したいmethodsを定義する。
<template> <div id="app"> <intersect @enter="hoge"> <div>intersectタグに囲まれたこの要素を表示したら、hogeメソッドが実行される</div> </intersect> </div> </template> <script> import Intersect from 'vue-intersect' export default { name: 'app', components: { Intersect }, methods: { hoge () { alert('表示された') } } } </script>
リストから初期10件アイテムを表示して、intersectが表示されたら5件ずつ表示するサンプル
よくある、スクロールしたら続きのアイテムが見れる動作をvue-intersectを使ってやってみた
<template> <div id="app"> <ul class="lists"> <li class="list" v-for="list in displayLists" :key="list">{{ list }}</li> </ul> <intersect @enter="moreList"> <div id="js-more-loading">Loading...</div> </intersect> </div> </template> <script> import Intersect from 'vue-intersect' export default { name: 'app', data () { return { // 元のアイテムリスト lists: [ '1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22' ], // 画面に表示するリスト displayLists:[], // 画面に表示するリスト数 listLimit: '', // 初期の画面に表示するリスト数 listLimitDefault: 10, // ローディング時に追加するリスト数 listLimitMore: 5, // ロードした回数 listLimitIncrement: 1 } }, components: { Intersect }, mounted () { // 初期10件表示 this.listLimit = this.listLimitDefault for (let i = 0; i < this.listLimit; i++) { if (this.lists[i]) { this.displayLists.push(this.lists[i]) } } }, methods: { moreList () { setTimeout(function () { // ローディング要素を非表示に document.getElementById('js-more-loading').classList.add('is-loaded') // displayListsに、ロードしたリストを代入する let lists = [] this.listLimit = this.listLimitDefault + (this.listLimitMore * this.listLimitIncrement) for (let i = 0; i < this.listLimit; i++) { if (this.lists[i]) { lists.push(this.lists[i]) } } this.displayLists = lists // listLimitIncrementのインクリメント this.listLimitIncrement = this.listLimitIncrement + 1 // ローディング要素を再表示 document.getElementById('js-more-loading').classList.remove('is-loaded') // アイテムを表示し終わったら、ローディング要素を非表示にする if (this.lists.length - this.listLimitMore <= this.listLimitMore * this.listLimitIncrement) { document.getElementById('js-more-loading').classList.add('is-loaded') return } }.bind(this), 500) }, } } </script> <style> .lists { min-height: 100vh; } .list { height: 20vh; } .is-loaded { display: none; } </style>
こんな感じになればOK
@enterだけでなく、@leaveや@changeで、見えなくなった時や状態変わった時も実行出来るので、アイデア次第で色々つかえそう https://github.com/heavyy/vue-intersect#events
IE11に対応する場合
intersection-observerのpolyfillの設定が必要。
polyfill導入方法
- npmインストール or scriptタグで導入する。
npm install intersection-observer
or
<script src="path/to/intersection-observer.js"></script>
- import Intersect from 'vue-intersect'の上とかに追記する。
require('intersection-observer')