html部分
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>infinite Scroll</title>
<link rel="stylesheet" href="./css/bootstrap.css">
<link rel="stylesheet" href="./css/style.css">
<script type="text/javascript" src="./js/common/mock.js"></script>
<script type="text/javascript" src="./js/common/axios.js"></script>
<script type="text/javascript" src="./js/common/vue.js"></script>
<script type="text/javascript" src="./js/index.js"></script>
<script type="text/javascript" src="./js/scroll.js"></script>
</head>
<body>
<div id="app" class="container">
<div class="header-title">
<h2>Vue+mockJS+axios实现无限滚动</h2>
</div>
<div class="body-content">
<div class="content-item" v-for="(item, i) in newList" :key="i">
<div class="item-left">
<img :src="item.image">
</div>
<div class="item-right">
<div class="item-right-title">
{{item.title}}
</div>
<div class="item-rigth-content">
{{item.content}}
</div>
</div>
</div>
</div>
<div class="footer-loading" v-show="loading">
<img src="./img/laoding.gif">
</div>
</div>
</body>
</html>
Css部分
* {
margin: 0;
padding: 0;
list-style: none;
}
.container {
width: 60%;
margin: 0 20%;
}
.header-title {
width: 100%;
color: #3d6f41;
background-color: #ddedd8;
padding: 1%;
}
.body-content {
width: 100%;
padding: 1%;
}
.content-item {
width: 100%;
color: #867586;
display: flex;
flex-direction: row;
padding: 1% 0;
border-bottom: 1px solid #f2f2f2;
}
.item-left {
width: 20%;
}
.item-left img {
width: 80%;
height: 80%;
}
.item-right {
width: 80%;
}
.item-right-title {
width: 100%;
font-size: 18px;
line-height: 20px;
}
.item-rigth-content {
width: 100%;
font-size: 16px;
line-height: 18px;
}
.footer-loading {
width: 100%;
text-align: center;
}
Vue部分
window.onload = () => {
const obj = {
data: {
pageIndex: 0,
pageSize: 11,
loading: false,
reachBottom: false,
newList: []
},
mounted () {
this.getNewList()
window.onscroll = () => {
this.reachBottom = this.getScrollHeight()
}
},
watch: {
reachBottom (newval, oldval) {
if(newval && !this.loading) {
this.getNewList()
}
}
},
methods: {
getNewList () {
this.loading = true
setTimeout(() => {
axios.post('http://localhost:8080/list', {
pageIndex: this.pageIndex,
pageSize: this.pageSize
}).then(res => {
console.log(res.data.data.curNewList)
const news = res.data.data.curNewList
for(let i = 0; i< news.length; i++) {
this.newList.push(news[i])
}
this.pageIndex++
this.loading = false
}).catch(err => {
console.log(err)
})
}, 2000)
},
// 计算滚动条是否到达底部
getScrollHeight () {
// 页面总高度 = 滚动条高度 + 可视区高度
const windowHeight = window.scrollY + window.innerHeight
console.log(windowHeight) // 此处如果遇到不是整数值可以使用(向上、向下取整)或者四舍五入
// 页面高度: document.docuemntElemnt.offsetHeight
return windowHeight == document.documentElement.offsetHeight
}
}
}
new Vue(obj).$mount('#app')
}
mock部分
const Random = Mock.Random
const newList = []
for(let i = 1; i <= 111; i++) {
const item = {
'image': Random.image('200x100', '#50B347', '#FFF', 'Mock.js'),
'title': Random.title(3),
'content': Random.sentence()
}
newList.push(item)
}
// 新闻列表接口
Mock.mock('http://localhost:8080/list', 'post', (params) => {
const info = JSON.parse(params.body)
console.log(info)
const [index, size] = [info.pageIndex, info.pageSize]
const curNewList = newList.slice(index * size, (index + 1) * size)
return {
'code': '0',
'message': 'success',
'data': {
'pageIndex': index,
'pageSize': size,
'curNewList': curNewList
}
}
})
总结,无限滚动需要明白滚动条高度和页面高度以及可是区域高度的关系,即页面高度=滚动条高度+可视区域高度,利用这个关系我们就可以知道当前滚动条是否滚动到底部,再利用watch来监视是否加载新的内容