当页面翻到最下面的时候,会自动发送请求去请求加载数据
组件代码
src/components/infinite.vue
<template>
<div class="xtx-infinite-loading" ref="target">
<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: 'XtxInfiniteLoading',
props: {
// 控制是否正在加载中
loading: {
type: Boolean,
default: false
},
// 数据是否全部加载完成
finished: {
type: Boolean,
default: false
}
},
setup (props, { emit }) {
const target = ref(null)
useIntersectionObserver(target, ([{ isIntersecting }]) => {
// target元素到达可视区
if (isIntersecting) {
// 触发加载事件条件:请求加载完成,数据加载完毕
if (!props.loading && !props.finished) {
emit('infinite')
}
}
}, { threshold: 0 })
return { target }
}
}
</script>
<style lang="less" scoped>
.xtx-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>
使用组件
<ul>
<li v-for="goods in goodsList" :key="goods.id">
<GoodsItem :goods="goods"></GoodsItem>
</li>
</ul>
<!-- 加载组件 -->
<XtxInfiniteLoading :loading="loading" :finished="finished" @infinite="getData"></XtxInfiniteLoading>
setup () {
const route = useRoute()
// 加载中
const loading = ref(false)
// 是否加载完毕
const finished = ref(false)
const goodsList = ref([])
// 请求参数
let requestParams = {
page: 1,
pageSize: 20
}
const getData = () => {
loading.value = true
// 设置二级分类的id
requestParams.categoryId = route.params.id
findCategoryGoods(requestParams).then(({ result }) => {
// 获取数据成功
if (result.items.length) {
goodsList.value.push(...result.items)
// 追加完成把page改成下一页
requestParams.page++
} else {
// 没有数据代表加载完成
finished.value = true
}
loading.value = false
})
}
// 在更改了二级分类后(路由)要重新加载goodsList数组
watch(() => route.params.id, (newVal) => {
if (newVal && `/category/sub/${route.params.id}` === route.path) {
finished.value = false
goodsList.value = []
requestParams = {
page: 1,
pageSize: 20
}
}
}, { immediate: true })
return {
getData,
loading,
finished,
goodsList
}
}