概述
首先我们得了解无限加载数据组件是一个什么东西?
它就是一个盒子, 简单来说就是一个 div ; 这一个盒子里面有两个子元素
1. loading 的效果
2. 父组件数据加载完毕之后的效果, 我取名为 finished
组件内部需要接收父组件传过来的 loading 和 finished 值, 在模板中使用 v-if 进行动态的判断; 到底需要显示哪一个效果
我们还需要了解一个问题就是, 什么时候什么条件的加持下; 该去发送数据, 在模板中渲染?
这个问题也跟此组件有关, 我们可以监听这个组件(也就是监听这个 div); 如果这个 div 出现在了可视区, 我们就通知父组件调用数据, 渲染数据即可
最后一个问题就是, 如何实现数据的无限加载?
实现的思想主要是使用的分页加载, 当前页面数据已经返回; 就到动态的将 page++ , 再次获取的数据和原先的数据进行合并; 这样的往复动作就可以实现数据无线加载
思路分析:
1. 父组件内部需要提供 loading 和 finished 数据, 传给子组件(无限加载组件)
2. 子组件内部通过 v-if 判断, 最终显示哪一个效果
3. 子组件内部还需提供监听模板元素的方法, 当监听对象进入可视区; 就通知父组件调用接口
4. 父组件需要接收子组件抛出的信息, 内部封装调用接口的函数; 收到消息就直接调用
5. 父组件中定义一个响应式的数组, 每一次后端的数据返回就动态的 push 进去; 且修改 page 值
<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 }], dom) => {
if (isIntersecting) {
if (props.loading === false && props.finished === false) {
// 如果两个状态都为false, 说明数据还可以继续加载且前一次数据已经响应完毕
emit('infinite')
}
}
},
{
threshold: 0
}
)
return { target }
}
}
</script>
<style scoped lang='less'>
.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>
<template>
<div class="sub-category">
<div class="container">
<!-- 二级类目面包屑 -->
<SubBread />
<!-- 筛选区 -->
<SubFilter />
<div class="goods-list">
<!-- 排序 -->
<SubSort />
<!-- 列表 -->
<ul>
<li v-for="item in goodsList" :key="item.id" >
<GoodsItem :goods="item" />
</li>
</ul>
<!-- 无限加载组件 -->
<!-- 此组件需要放在列表组件后面, 组件初始化的时候; 商品列表是空的, 所以此组件一开始就会在可视区里面 -->
<XtxInfiniteLoading :loading="loading" :finished="finished" @infinite="getData" />
</div>
</div>
</div>
</template>
<script>
import SubBread from './components/sub-bread.vue'
import SubFilter from './components/sub-filter'
import SubSort from './components/sub-sort'
import GoodsItem from './components/goods-item'
import { findSubCategoryGoods } from '@/api/category'
import { ref, watch } from 'vue'
import { useRoute } from 'vue-router'
export default {
name: 'SubCategory',
components: { SubBread, SubFilter, SubSort, GoodsItem },
setup () {
// 控制无限加载组件的数据
const loading = ref(false)
const finished = ref(false)
const route = useRoute()
// 分页显示数据
let reqParams = {
page: 1,
pagsize: 20,
categoryId: route.params.id
}
// 后端返回的数据集合
const goodsList = ref([])
// 获取商品数据函数
const getData = () => {
loading.value = true
findSubCategoryGoods(reqParams).then(({ result }) => {
// 数据还有
if (result.items.length) {
goodsList.value.push(...result.items)
reqParams.page++
} else {
// 数据已经加载完毕
finished.value = true
}
loading.value = false
})
}
// 二级类目路由id发生变化立即进行
watch(() => route.params.id, (newVal) => {
if (newVal && route.path === `category/sub/${newVal}`) {
// 清空原先商品id所获取的数据
goodsList.value = []
// 初始化后端需求数据
reqParams = {
page: 1,
pagsize: 20,
categoryId: newVal
}
// 将finished效果隐藏
finished.value = true
}
}, { immediate: true })
return { loading, finished, goodsList, getData }
}
}
</script>
<style scoped lang="less">
.goods-list {
background: #fff;
padding: 0 25px;
margin-top: 25px;
ul {
display: flex;
flex-wrap: wrap;
padding: 0 5px;
li {
margin-right: 20px;
margin-bottom: 20px;
&:nth-child(5n) {
margin-right: 0;
}
}
}
}
</style>
最后
以上就是甜美小甜瓜为你收集整理的组件封装 - 无限加载数据组件的全部内容,希望文章能够帮你解决组件封装 - 无限加载数据组件所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复