前端react&vue3——实现滚动到底加载数据

yma16 2024-10-24 17:03:02 阅读 76

文章目录

⭐前言⭐react 实现滚动加载⭐vue3 实现滚动加载⭐总结⭐结束

⭐前言

大家好,我是yma16,本文分享 前端react&vue3——实现滚动加载(到底部加载)

scrollTop 属性

一个双精度浮点值,表示元素当前从原点垂直滚动的像素数,其中正值表示元素向下滚动(以显示更多底部的内容)。如果元素根本没有向上或向下滚动,则 scrollTop 为 0。如果文档不是活动文档,则返回值为 0。如果文档在亚像素精度设备上呈现,则返回的值也是亚像素精度的,可能包含小数部分。

clientHeight 属性

只读属性 Element.clientHeight 对于没有定义 CSS 或者内联布局盒子的元素为 0;否则,它是元素内部的高度(以像素为单位),包含内边距,但不包括边框、外边距和水平滚动条(如果存在)。

clientHeight 可以通过 CSS height + CSS padding - 水平滚动条高度(如果存在)来计算。

scrollHeight 属性

scrollHeight 只读属性是一个元素内容高度的度量,包括由于溢出导致的视图中不可见内容

node系列往期文章

node_windows环境变量配置

node_npm发布包

linux_配置node

node_nvm安装配置

node笔记_http服务搭建(渲染html、json)

node笔记_读文件

node笔记_写文件

node笔记_连接mysql实现crud

node笔记_formidable实现前后端联调的文件上传

node笔记_koa框架介绍

node_koa路由

node_生成目录

node_读写excel

node笔记_读取目录的文件

node笔记——调用免费qq的smtp发送html格式邮箱

node实战——搭建带swagger接口文档的后端koa项目(node后端就业储备知识)

node实战——后端koa结合jwt连接mysql实现权限登录(node后端就业储备知识)

node实战——koa给邮件发送验证码并缓存到redis服务(node后端储备知识)

koa系列项目文章

前端vite+vue3结合后端node+koa——实现代码模板展示平台(支持模糊搜索+分页查询)

node+vue3+mysql前后分离开发范式——实现对数据库表的增删改查

node+vue3+mysql前后分离开发范式——实现视频文件上传并渲染

koa-vue性能监控到封装sdk系列文章

性能监控系统搭建——node_koa实现性能监控数据上报(第一章)

性能监控系统搭建——vue3实现性能监控数据展示(第二章)

性能监控计算——封装带性能计算并上报的npm包(第三章)

canvas系列文章

web canvas系列——快速入门上手绘制二维空间点、线、面

webgl canvas系列——快速加背景、抠图、加水印并下载图片

webgl canvas系列——animation中基本旋转、平移、缩放(模拟冒泡排序过程)

⭐react 实现滚动加载

判断滚动到底部:<code>Math.ceil(scrollTop+clientHeight+1)>= scrollHeight

这里+1和向上取整是考虑到scrollTop是浮点数

react demo 案例:

import { -- --> useEffect, useRef, useState, useCallback } from 'react';

import { Button,notification} from 'tdesign-react'

const ScrollDemo=(props:any,ref:any)=> {

// @ts-ignore 列表数据

const [listData,setListData]=useState<any>([])

// ref

const scrollRef=useRef<HTMLElement|any>(null);

// 初始化数据

const initData=()=>{

const data=[];

for(let i=1;i<50;++i){

data.push({

label:`label${ i}`,

value:`label${ i}`,

})

}

return data

};

// 重置

const resetData=()=>{

setListData(initData())

};

//追加数据

const appendData=useCallback(()=>{

const data=[];

const length=listData.length

for(let i=length+1;i<10+length;++i){

data.push({

label:`label${ i}`,

value:`label${ i}`,

})

}

setListData(listData.concat(data))

},[listData])

//滚动事件

const scrollEvent=(e:any)=>{

console.log('e',e)

// 不使用滚动条的情况下为了适应视口中所用内容所需的最小高度

const scrollHeight=e.target.scrollHeight

// 从其顶部边缘滚动的像素数

const scrollTop=e.target.scrollTop

// dom 视口高度(不包含任何滚动条)

const clientHeight=e.target.clientHeight

console.log('scrollTop',scrollTop)

console.log('clientHeight',clientHeight)

console.log('scrollHeight',scrollHeight)

// 向上取整

if(Math.ceil(scrollTop+clientHeight+1)>= scrollHeight ){

notification.info({

title: '到底啦!',

})

appendData()

}

}

//监听 dom滚动

const listenDomScroll=()=>{

try{

if(scrollRef.current){

//@ts-ignore

scrollRef.current.removeEventListener('scroll',scrollEvent)

scrollRef.current.addEventListener('scroll',scrollEvent)

}

}

catch (e) {

console.error(e)

}

};

// 初始化

useEffect(()=>{

resetData()

},[])

// 数据变化重新监听dom

useEffect(()=>{

if(scrollRef.current){

listenDomScroll()

}

},[scrollRef,listData])

return <div style={ { padding:'10px',textAlign:'left'}}>

<Button onClick={ resetData} style={ { margin:'10px'}}>

重置

</Button>

<div>

<div style={ { maxHeight:'300px',width:'200px',overflowY:'auto',}} ref={ scrollRef}>

{ listData.map((item:any)=>{

return <div key={ item.value} style={ { background:'#0052d9',color:'#fff',margin:'2px',padding:'2px'}}>{ item.label}</div>

})}

</div>

</div>

</div>

};

export default ScrollDemo

效果:

react-scroll-demo

⭐vue3 实现滚动加载

vue3 demo 实例:

<code><script setup lang="ts">code>

import { -- --> ref, reactive, onMounted } from 'vue'

import { notification } from 'ant-design-vue'

const scrollRef = ref()

type ListDataType = { label: string, value: string }

// 初始化数据

const initData = (): ListDataType[] => {

const data: ListDataType[] = [];

for (let i = 1; i < 50; ++i) {

data.push({

label: `label${ i}`,

value: `label${ i}`,

})

}

return data

};

// state

const state: any = reactive({

listData: initData()

})

// 重置

const resetData = () => {

state.listData = initData()

};

//追加数据

const appendData = () => {

const data: any = [];

const length = state.listData.length

for (let i = length + 1; i < 10 + length; ++i) {

data.push({

label: `label${ i}`,

value: `label${ i}`,

})

}

state.listData = [...state.listData, ...data]

}

//滚动事件

const scrollEvent = (e: any) => {

console.log('e', e)

// 不使用滚动条的情况下为了适应视口中所用内容所需的最小高度

const scrollHeight = e.target.scrollHeight

// 从其顶部边缘滚动的像素数

const scrollTop = e.target.scrollTop

// dom 视口高度(不包含任何滚动条)

const clientHeight = e.target.clientHeight

console.log('scrollTop', scrollTop)

console.log('clientHeight', clientHeight)

console.log('scrollHeight', scrollHeight)

// 向上取整

if (Math.ceil(scrollTop + clientHeight + 1) >= scrollHeight) {

notification.open({

message: '到底啦!',

})

appendData()

}

}

//监听 dom滚动

const listenDomScroll = () => {

try {

if (scrollRef.value) {

//@ts-ignore

scrollRef.value.removeEventListener('scroll', scrollEvent)

scrollRef.value.addEventListener('scroll', scrollEvent)

}

}

catch (e) {

console.error(e)

}

};

// 初始化页面

onMounted(() => {

listenDomScroll()

})

</script>

<template>

<div>

<a-button type="primary" @click="resetData">重置</a-button>code>

<div style="max-height:300px;overflow-y:auto;width:200px" ref="scrollRef">code>

<div v-for="item in state.listData" :key="item.value"code>

style="background:#0052d9;color:#fff;padding:2px;margin:2px;">code>

{ -- -->{ item.label }}

</div>

</div>

</div>

</template>

效果:

vue-scroll-demo

代码块inscode

⭐总结

底部加载的关键判断条件是:Math.ceil(scrollTop + clientHeight + 1) >= scrollHeight。

在使用react时,需要注意通过dom监听数据的变化。而在使用vue3时,数据具有响应式特性,因此只需在滚动加载时添加数据即可。

⭐结束

本文分享到这结束,如有错误或者不足之处欢迎指出!

在这里插入图片描述

👍 点赞,是我创作的动力!

⭐️ 收藏,是我努力的方向!

✏️ 评论,是我进步的财富!

💖 最后,感谢你的阅读!



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。