Twitter や Facebook みたいにスクロールして下段まで行くと追加でデータをロードしてくれるあれを Vue を使って試したいと思います。
今回は Qiita の API を使用してデータを取得し、無限スクロールしていこうと思います。
使用ライブラリ
便利な無限スクロールライブラリがあるはずなので探してみました。
参考にしたサイト:
vuejsで無限ロードを実装 - Qiita
vue-infinite-scroll や vue-infinite-loading というのがあるようです。
GitHub のスターの数は前者のほうが 1,800 位で後者のほうは 1,400 位。ただ、活発に活動しているのは後者。
先行となる vue-infinite-scroll のいい所も取り込んでいるだろうし、今回は後者の vue-infinite-loading を使ってみたいと思います。
公式サイト:
Vue-infinite-loading
プロジェクトの準備
vue プロジェクトの雛形作成
vue-cli を使用して雛形プロジェクトを準備します。やり方は次の記事を参考にしてください。
プロジェクト名は「inf-loding」としました。
www.shookuro.com
ライブラリのインストール
npm を使用してライブラリをインストールします 。
まずは、vue-infinite-loading。
npm install vue-infinite-loading -S
次に Ajax ライブラリの axios 。
npm install axios -S
ファイルの整理
vue ファイルは src/ 配下の App.vue のみ使用するので、src/components/ 配下の HelloWorld.vue は削除してしまいます。
コーディング
App.vue の編集
というか App.vue しか編集しません。
細かい編集内容は割愛。最後に App.vue の全量を掲載しておきます。
style の削除
見た目はショボくてもいいので、以下の <style> タグは削除してしまいましょう。
<style> /* タグごと全部消す */ #app { font-family: "Avenir", Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
script の編集
InfiniteLoading と axios を import します。
import InfiniteLoading from 'vue-infinite-loading' import axios from 'axios'
Qiita 記事取得 API の URL を定数として保持します。
const api = 'https://qiita.com/api/v2/items'
components に IniniteLoading を登録します。これで <infinite-loading> カスタムタグが利用可能になります。
components: { InfiniteLoading },
data には現在読み込み完了したページ番号( page )と、実際のデータ( list )を保持しておきます。
data() { return { page: 1, list: [], } },
メソッドには追加読み込みのイベントが発生したときのハンドラを定義しておきます。InfiniteLoding が自動でイベントを発火しますので、開発者は呼び出しません。
methods: { infiniteHandler($state) {
axios を使って API を呼び出します。headers の Authorization は Qiita で取得した個人用アクセストークンを設定します。
今回使用する API の場合、アクセストークンがなくてもいいのですがその場合、1 時間に 60 回しか API 呼び出しできません。XXX・・・の部分は自分のアクセストークンを指定してください。
axios.get(api, { params: { page: this.page, per_page: 20 }, headers: { 'Authorization' : 'Bearer ' + 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' } }).then(({ data }) => { if (data.length) { this.page += 1 this.list.push(...data) $state.loaded() } else { $state.complete() } }).catch((err) => { $state.complete() })
1 レコード以上読み込みできた場合は $state.loaded() を呼び出します。
1 レコードも読み込まれなかった場合は、これ以上データがないと判断し、$state.complete() を呼び出します。そうすると追加読み込みイベントが発火しなくなります。
今回は、エラーの場合も $state.complete() にしてしまっていますが、ここはシステムにより適切にハンドリングしましょう。
template の編集
table の tr タグに v-for を仕込んで保持しているデータの数だけループさせます。
<table> <tr v-for="(item, $index) in list" :key="$index"> <td><a :href="item.url">{{item.title}}</a></td> </tr> </table>
table の下に InfiniteLoding のカスタムタグを追加し、追加読み込みイベントのハンドラ ( infiniteHandler ) を指定します。
<infinite-loading @infinite="infiniteHandler"></infinite-loading>
このタグには InfiniteLogind で用意されているオプションも v-bind で指定できます。
オプションの一覧はこちら。
API | Vue-infinite-loading
例えば、どのくらい画面の下までスクロールしたら追加読み込みイベントを発火させるか調節する場合、distance プロパティを指定します。
デフォルトは 100 です。これを 1,000 にすると、ちょっと下にスクロールしただけで追加読み込みが発生します。 ( v-bind は : に省略可)
<infinite-loading @infinite="infiniteHandler" :distance="1000"></infinite-loading>
他にもスピナー(くるくる回るやつ)の種類や読み込むデータがないときに表示するメッセージなど設定できます。
完成
完成しました。
まとめ
Vue で、InfiniteLoding というライブラリと Qiita API を使用した無限スクロールの実装を行いました。
割と簡単に実装できます。Twitter や Facebook の クライアントを作成するときに使えそうです。
最後に App.vue の全量を貼っておきます。
<template> <div> <table> <tr v-for="(item, $index) in list" :key="$index"> <td><a :href="item.url">{{item.title}}</a></td> </tr> </table> <infinite-loading @infinite="infiniteHandler"></infinite-loading> </div> </template> <script> import InfiniteLoading from 'vue-infinite-loading' import axios from 'axios' const api = 'https://qiita.com/api/v2/items' export default { name: "app", components: { InfiniteLoading }, data() { return { page: 1, list: [], } }, methods: { infiniteHandler($state) { axios.get(api, { params: { page: this.page, per_page: 20 }, headers: { 'Authorization' : 'Bearer ' + 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' } }).then(({ data }) => { if (data.length) { this.page += 1 this.list.push(...data) $state.loaded() } else { $state.complete() } }).catch((err) => { $state.complete() }) } } } </script>
それでは!
- 作者: 川口和也,喜多啓介,野田陽平,手島拓也,片山真也
- 出版社/メーカー: 技術評論社
- 発売日: 2018/09/22
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
改訂新版 Vue.jsとFirebaseで作るミニWebサービス (技術書典シリーズ(NextPublishing))
- 作者: 渡邊達明
- 出版社/メーカー: インプレスR&D
- 発売日: 2018/10/05
- メディア: Kindle版
- この商品を含むブログを見る
- 作者: mio
- 出版社/メーカー: シーアンドアール研究所
- 発売日: 2018/05/29
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る