一个独立的组件全局:如果他可见,通知加载下一页数据,如果加载成功它自己就会被挤到下边—又变成了不可见了。
注意:它自己不保存数据
1.组件代码
src/components/xtx-infinite-loading.vue
<template>
<div class="xtx-infinite-loading" ref="container">
<!-- 正在加载数据时显示 -->
<div class="loading" v-if="isLoading">
<span class="img"></span>
<span class="text">正在加载...</span>
</div>
<!-- 数据全部加载完毕时显示 -->
<div class="none" v-if="isFinished">
<span class="text">亲,没有更多了</span>
</div>
</div>
</template>
<script>
import { ref } from 'vue'
import { useIntersectionObserver } from '@vueuse/core'
export default {
name: 'XtxInfiniteLoading',
emits: ['load'],
props: {
// 是否在加载中
isLoading: {
type: Boolean,
default: false
},
// 数据全部加载完毕
isFinished: {
type: Boolean,
default: false
}
},
setup (props, { emit }) {
const container = ref(null)
useIntersectionObserver(
container,
([{ isIntersecting }], dom) => {
if (isIntersecting) {
// 只有数据不在加载中且还没全部结束时才触发load事件
if (props.isLoading === false && props.isFinished === false) {
emit('load')
}
}
},
{
threshold: 0
}
)
return { container }
}
}
</script>
2.组件使用
sub.vue
<!-- 列表 -->
<div class="sort-list-container">
<GoodsItem v-for="good in goodsList" :key="good" :good="good" />
</div>
<!-- 上拉加载 -->
<XtxInfiniteLoad @load="loadData" :isFinished="isFinished" :isLoading="isLoading"/>
setup(){
//这里使用了逻辑抽离
const { subCate } = useSubCate()
+ const { isFinished, isLoading, loadData, goodsList, hFilterChange, hSortChange } = useLoadData()
+ return { subCate, goodsList, hFilterChange, hSortChange, loadData, isLoading, isFinished }
}
3.修改useLoaddata
const useLoadData = () => {
const route = useRoute()
// 请求参数
let reqParams = {
categoryId: route.params.id,
inventory: null, // 是否只显示有库存
onlyDiscount: null, // 是否只显示有优惠
brandId: null, // 品牌名称
attrs: [], // 商品属性
sortField: null, // 排序类别
sortMethod: null, // 排序的方式
page: 1,
pageSize: 20
}
const goodsList = ref([]) // 保存查询结果
+ const isLoading = ref(false)
+ const isFinished = ref(false)
const loadData = () => {
+ isLoading.value = true
findSubCategoryGoods(reqParams).then(data => {
console.log('findSubCategoryGoods', data)
// 新数据要追加到数组中
+ goodsList.value.push(...data.result.items)
// 页码加1
+ reqParams.page++
// 判断是否加载完成
+ if (data.result.items.length === 0) {
+ isFinished.value = true
}
+ isLoading.value = false
})
}
const hFilterChange = (filterParam) => {
console.log('父组件收到了筛选条件', filterParam)
// 更新条件
// reqParams.brandId = filterParam.brandId
// reqParams.attrs = filterParam.attrs
reqParams = { ...reqParams, ...filterParam }
// 重发请求
loadData()
}
const hSortChange = (sortParam) => {
console.log('父组件收到了排序条件', sortParam)
// 更新条件
// reqParams.inventory = sortParam.inventory
// reqParams.onlyDiscount = sortParam.onlyDiscount
reqParams = { ...reqParams, ...sortParam }
// 重发请求
loadData()
}
loadData()
return { isFinished, isLoading, goodsList, hFilterChange, hSortChange, loadData }
}