ゴール
ざっくりの流れ
スクリプト
API
APIを叩くと、仮にこんな感じのjsonが返ってくる。
{
"page": 1,
"pages": 4,
"projects": [
{
"author": {
"name": "Keita Imatomi",
"portrait": "user/0001/thumbnail.jpg",
"username": "imatomix"
},
"id": 2,
"public": true,
"thumbnail": "project/0022/thumbnail.jpg",
"title": "zcvz"
},
{
"author": {
"name": "Keita Imatomi",
"portrait": "user/0001/thumbnail.jpg",
"username": "imatomix"
},
"id": 3,
"public": true,
"thumbnail": "project/0021/thumbnail.jpg",
"title": "asd"
},
...
]
}
Vue
<template>
<article id="gallery">
<div class="grid">
<div class="col-xs-6 col-sm-4 col-md-3 col-lg-2 col-xl-2"
v-for="project in projects"
:key="project.id"
v-if="project.public">
<Card :project="project"></Card>
</div>
</div>
<div id="infscr-loading" v-if="isLoading">
<img src="/static/image/icon_loading.gif">
</div>
</article>
</template>
<script>
import axios from 'axios'
import Card from '../ui/Card.vue'
const URL = '/api/v1/projects/'
export default{
components: {
Card
},
data: function(){
return {
projects: [],
page: 1, // 次に読み込むページ数
isLoading: false
}
},
// 最初に1ページ目を読み込む。スクロールイベントリスナーを登録する。
created: function(){
this.fetchProjects()
window.addEventListener('scroll', this.scroll)
},
destroyed: function(){
window.removeEventListener('scroll', this.scroll)
},
methods:{
fetchProjects: function(){
if(this.isLoading == false){
this.isLoading = true
axios.get(URL + this.page)
.then((response) => {
this.projects = this.projects.concat(response.data.projects)
this.page++
// 次のページがページ総数を上回ったらisLoadingをundefineにして読み込み停止
this.isLoading = (this.page > response.data.pages)? undefined : false
})
.catch((error) => {
console.log(error)
})
}
},
scroll: function(e){
// #galleryの底辺が画面に入ったら次のページを読み込む
if(gallery.getBoundingClientRect().bottom < window.innerHeight){
this.fetchProjects()
}
}
}
}
</script>