今天我们手动封装一个下拉加载更多组件,类似于vant组件库中的list功能
loading.vue
<template>
<div class="infinite-loading" ref="container">
<div class="loading" v-if="loading">
<span class="img"></span>
<span class="text">正在加载...</span>
</div>
<div class="none" v-if="finished">
<span class="img"></span>
<span class="text">亲,没有更多了</span>
</div>
</div>
</template>
<script>
import { ref } from 'vue'
import { useIntersectionObserver } from '@vueuse/core'
export default {
name: 'InfiniteLoading',
props: {
loading: {
// 判断上一页数据是否加载完成
type: Boolean,
default: false
},
// 判断列表是否还有更多数据可以加载
finished: {
type: Boolean,
default: false
}
},
setup(props, { emit }) {
const container = ref(null)
useIntersectionObserver(
// 参数一:被监听的dom元素
container,
([{ isIntersecting }], dom) => {
if (isIntersecting) {
// 进入可视区了,发请求获取下一页数据
// 发请求的条件:上一次数据已经加载完成,且 列表还有更多数据可以加载
if (props.loading === false && props.finished === false) {
emit('infinite')
}
}
},
{
threshold: 0
}
)
return { container }
}
}
</script>
<style scoped lang="less">
.infinite-loading {
.loading {
display: flex;
align-items: center;
justify-content: center;
height: 200px;
.img {
width: 50px;
height: 50px;
background: url(../../assets/images/load.gif) no-repeat center / contain;
}
.text {
color: #999;
font-size: 16px;
}
}
.none {
display: flex;
align-items: center;
justify-content: center;
height: 200px;
.img {
width: 200px;
height: 134px;
background: url(../../assets/images/none.png) no-repeat center / contain;
}
.text {
color: #999;
font-size: 16px;
}
}
}
</style>
加载更多组件封装好啦,我们直接在其他组件用就可以了,只要给组件传两个属性,一个是loading 一个是finished,通过这两个标志类来进行数据的加载更多
loading:判断上一次数据是否加载完
finished:判断是否还有数据