上拉加载更多的分页功能大家应该都见过或者使用过了吧,那么有多少同学自己实现过吗,本文我们来简单实现一个上拉加载更多分页组件吧
目录
效果展示体验地址实现思路1、组件模板结构2、组件属性(props)3、组件数据(data)4、组件生命周期(mounted)5、组件方法(methods)组件使用组件库效果展示
体验地址
jyeontu.xyz/jvuewheel/#/JPageContentView
实现思路
1、组件模板结构
<template> <div class="j-page-content" ref="scrollable" @scroll="handleScroll"> <slot></slot> <div v-if="loading" class="loading-indicator">{{ moreText }}</div> </div></template>可滚动容器:最外层是一个内容容器,并且设置了
@scroll
事件监听器,当用户滚动这个容器时,会触发 handleScroll
方法。内容插槽:<slot>
元素用于接收外部传入的内容。这意味着使用者可以在使用该组件时,将需要展示的列表项或者其他内容放置在这个组件内部,灵活性很高。加载提示:当 loading
为 true
时,会显示一个带有加载文本的 div
。加载文本通过 moreText
属性传入,默认值为 "加载中..."。这个加载提示元素位于容器底部。2、组件属性(props)
props: { moreText: { type: String, default: "加载中...", }, threshold: { type: String, default: "20", },}moreText:用于定义加载提示文本的内容。外部使用者可以根据自己的应用场景和语言需求,自定义这个文本。threshold:用于设置判断接近容器底部的阈值。默认值为 "20",它表示当距离容器底部的距离小于等于这个阈值时,触发加载更多的操作。这个值可以根据实际的设计需求和视觉效果进行调整。
3、组件数据(data)
data() { return { loading: false, isNearBottom: false, scrollableElement: null, isloading: false, };}loading:用于表示当前是否正在加载更多数据。初始值为
false
,当触发加载更多操作时,设置为 true
,加载完成后再重置为 false
。isNearBottom:用于判断是否接近容器底部。通过在滚动事件处理中计算得到,初始值为 false
。scrollableElement:用于存储可滚动容器的引用。在组件挂载(mounted
)阶段获取到对带有 ref="scrollable"
的 div
的引用。isloading:这是一个额外的加载状态标识,用于在加载过程中防止多次触发加载更多操作。初始值为 false
,在触发加载更多操作时设置为 true
,并在加载完成后的短暂延迟后重置为 false
。4、组件生命周期(mounted)
mounted() { this.scrollableElement = this.$refs.scrollable;}
这里通过 this.$refs.scrollable
获取到在模板中定义的可滚动容器的引用,并将其赋值给 scrollableElement
,以便在后续的滚动事件处理中使用。
5、组件方法(methods)
(1) handleScroll 方法
handleScroll() { if (this.isloading) return; const scrollTop = this.scrollableElement.scrollTop; const clientHeight = this.scrollableElement.clientHeight; const scrollHeight = this.scrollableElement.scrollHeight; // 判断是否接近底部 this.isNearBottom = scrollTop + clientHeight >= scrollHeight - this.threshold; if (this.isNearBottom &&!this.loading) { this.loading = true; this.isloading = true; this.$emit("loadMore"); }}首先,该方法会检查
isloading
的状态,如果正在加载(isloading
为 true
),则直接返回,避免多次触发加载操作。然后,获取可滚动容器的当前滚动位置(scrollTop
)、可视区域高度(clientHeight
)以及整个可滚动内容的高度(scrollHeight
)。通过计算判断是否接近底部(scrollTop + clientHeight >= scrollHeight - this.threshold
)。如果接近底部且当前没有在加载(!this.loading
),则将 loading
和 isloading
都设置为 true
,并通过 this.$emit("loadMore")
向外抛出一个名为 loadMore
的自定义事件。父组件可以监听这个事件来执行加载更多数据的操作。(2)loadMoreComplete 方法
loadMoreComplete() { this.loading = false; setTimeout(() => { this.isloading = false; }, 100);}
当父组件完成加载更多数据的操作后,应该调用这个方法。它首先将 loading
设置为 false
,表示加载操作已完成。然后,通过 setTimeout
设置一个 100 毫秒的延迟后,将 isloading
也设置为 false
。这样的延迟是为了确保在加载完成后的短暂时间内不会再次触发加载更多操作,避免可能出现的问题。
组件使用
<template> <div class="content" style="height: 500px"> <JPageContent @loadMore="loadMoreData" ref="JPageContent"> <div v-for="n in nums" :key="n"> <div style=" height: 100px; width: 400px; text-align: center; line-height: 100px; border: 1px solid gray; " > JPageContent-{{ n }} </div> </div> </JPageContent> </div></template><script>export default { data() { return { nums: 10, } }, methods: { loadMoreData() { if (this.nums >= 30) { this.$refs.JPageContent.loadMoreComplete(); return; } setTimeout(() => { this.nums += 10; this.$refs.JPageContent.loadMoreComplete(); }, 1000); } }}</script>
组件库
组件文档
目前该组件也已经收录到我的组件库,组件文档地址如下: jyeontu.xyz/jvuewheel/#/JPageContentView