首先简单看下需求,项目中工作台页面有个小模块,大概功能是需要实现该模块中的下拉加载数据,并且实现input框的实时输入搜索。如下图所示:
后端给出的接口已经实际上是一个支持通过患者姓名和分页参数来查询的接口,主要看一下前端如何实现,直接上重点代码:
<template>
<div
id="followData"
v-loading="loading"
element-loading-background="rgba(0, 0, 0, 0)"
class="follow-class"
>
......
<div v-if="ifDataEmpty" class="default-box">
<img src="XXXXXX" alt="">
<div class="default-txt">暂无搜索结果</div>
</div>
</div>
</template>
首先是 HTML 代码部分,这部分的重点是需要给最外层父元素一个 id ,后面需要操作 dom 元素,图中的 v-loading 是 Element-UI 的加载组件。
<style lang="scss" scoped>
.follow-class {
width: 100%;
height: 774px;
padding: 0 10px;
background: #ECF0F6;
border-radius: 7px;
border: 1px solid #FFFFFF;
overflow: scroll;
overflow-x: hidden;
&::-webkit-scrollbar {
width: 4px;
background: white;
}
&::-webkit-scrollbar-corner,
&::-webkit-scrollbar-thumb,
&::-webkit-scrollbar-track {
border-radius: 4px;
}
&::-webkit-scrollbar-corner,
&::-webkit-scrollbar-track {
background-color: rgba(180, 160, 120, 0.1);
box-shadow: inset 0 0 1px rgba(180, 160, 120, 0.5);
}
&::-webkit-scrollbar-thumb {
background-color: rgba(144,147,153,.5);
}
...... 其他CSS代码 ......
</style>
CSS 代码重点部分是 height: 774px 、overflow: scroll 和 overflow-x: hidden
首先需要固定一个高度,然后将滚动条调出来,隐藏 x 轴滚动条,其他的一大段代码是设置滚动条样式的,浏览器原来的滚动条不美观。
接下来看 JS 部分代码:
先来看 data 中的数据
export default {
data() {
return {
loading: false,
title: '',
page: {
pageNumber: 1,
pageSize: 8
},
total: '',
ifDataEmpty: false
}
}
}
再看一下 methods 中的几个重点方法:
bindEventListener() {
this.$nextTick(() => {
const el = document.getElementById('followData')
if (!el) return
el.addEventListener('scroll', _.throttle(this.scrollHandler, 200))
})
}
scrollHandler() {
const divHeight = document.getElementById('followData').offsetHeight
const nScrollHeight = document.getElementById('followData').scrollHeight
const nScrollTop = document.getElementById('followData').scrollTop
if (nScrollTop + divHeight + 1 >= nScrollHeight) {
this.page.pageNumber = parseInt(this.page.pageNumber + 1)
if (this.page.pageNumber > parseInt(this.total)) {
return false
}
this.getData('1')
}
}
关于 offsetHeight、scrollHeight、scrollTop 这三个属性一定要了解,不清楚的可以自寻网上学习。
本方法主要是用于判断滚动条是否滚动到最底部。若滚动到最底部的时候,将 pageNumber 自加一,如果此时的 pageNumber 小于总页数,就请求下一页的数据;如果大于总页数,就 return 出来,因为已经是最后一页了,不需要再请求数据了。
然后就是请求接口数据的方法:
getData(type) {
this.loading = true
getPageList({
title: this.title
}, this.page).then(res => {
this.loading = false
const _result = res
const _data = _result.content
this.total = _result.totalPages
type === '1' ? this.followList = this.followList.concat(_data) : this.followList = _data
if (type === '2') {
_data.length === 0 ? this.ifDataEmpty = true : this.ifDataEmpty = false
}
}).catch(() => {
this.loading = false
this.$message.warning('加载失败')
})
}
重点在于请求分页接口的两种情况。一种情况是整页的查询,你在下拉滚动到底部时请求接口获取下一页数据之后,数据是拼接在前一页数据后面的,所以要用 concat 方法拼接,如果直接赋值的话前一页数据就被覆盖了;另一种是你在输入时的实时查询,就要将页面数据先置空,重新赋值接口搜索出来的数据。
接着是实时输入时的搜索:
searchChange(value) {
this.title = value
this.page = {
pageNumber: 1,
pageSize: 8
}
if (this.ifDataEmpty !== true) {
document.getElementById('followData').scrollTop = 0
}
this.getData('2')
}
最后,记得及时销毁之前绑定的滚动事件:
destroyed() {
const el = document.getElementById('followData')
el && el.removeEventListener('scroll', this.scrollHandler)
}
好了,这样子就完美实现了,该方法同样适用于移动端,你也可以用各种插件来实现这种下拉滚动加载的效果,本方法是原生方法来实现的,欢迎补充互相学习~
|