【vue scrollTo 数据无限滚动 】

2024-06-21 10:44

本文主要是介绍【vue scrollTo 数据无限滚动 】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

vue数据无限滚动
参考来源 Vue3 实现消息无限滚动的新思路 —— 林三心不学挖掘机
在这里插入图片描述
vue3代码

<template><div class="scroll-container" ref="scrollRef"><div v-for="(item, index) in list" :key="index" style="height: 40px; line-height: 40px;">{{ item.title }}</div></div>
</template><script setup>
import  { onMounted, ref } from 'vue'
defineOptions({name: 'publicRecruitment-bountyDisplay'})// 容器的 dom 节点
const scrollRef = ref()
// 模拟列表数据
const dataSource = new Array(10).fill(0).map((_, index) => ({title: `这是一条信息${index}`
}))
const list = ref([...dataSource])// 记录原始数据的长度
const len = dataSource.length
onMounted(() => {// 滚动的距离let top = 0// 索引let index = 0const scroll = () => {// 垂直方向滚动scrollRef.value?.scrollTo({top: top++})if (top % 40 === 0) {// 哪一项滚不见了,就拿这一项 push 到列表中const target = list.value[index]if (target) list.value.push(target)if (index < (len - 1)) {// 不断递增index++} else {// 刚好滚动完一轮,重新来过,初始化数据top = 0index = 0scrollRef.value?.scrollTo({top: 0})list.value = [...dataSource]}}// 不断滚动requestAnimationFrame(scroll)}scroll()
})
</script><style lang="scss" scoped>
.scroll-container {//   防止有滚动条出现overflow: hidden;height: 150px;
}
</style>

兼容升级版本
1.如果数据长度形成的总高度少于容器高度,不设置滚动
2.如果数据长度仅高于容器高度不足一个数据单位的长度会出现抖动滚动。解决方法:将数据复制一份

删减代码

在这里插入图片描述

<!-- 滚动展示 -->
<template><div style="height: 100%; width: 100%;"><div class="mb-3" style="font-size: 13px; color: #666;">无缝衔接滚动</div><!-- 滚动 --><divclass="scroll-container"ref="scrollRef"style="height: calc(100% - 32px); overflow: hidden; font-size: 13px;color: #333;"><!-- 数据list --><divv-for="(item) in list":key="item.name"class="d-flex justify-space-between align-center":style="`height: ${dataItemHeight}px;`"><div class="ml-2">{{ item.name }}</div></div></div></div>
</template><script setup>
import  { onMounted, ref } from 'vue'
defineOptions({name: 'publicRecruitment-bountyDisplay'})
// 滚动实现代码部分
const dataItemHeight = 40
// 容器的 dom 节点
const scrollRef = ref()
// // 模拟列表数据
let listSource = new Array(10).fill(0).map((_, index) => ({ name: `name${index}`}))
const list = ref([...listSource])// 记录原始数据的长度
let len = listSource.length
onMounted(() => {// 滚动的距离let top = 0// 索引let index = 0const scroll = () => {// 垂直方向滚动scrollRef.value?.scrollTo({top: top++,})if (top % dataItemHeight === 0) {// 哪一项滚不见了,就拿这一项 push 到列表中const target = list.value[index]if (target) list.value.push(target)if (index < len - 1) {// 不断递增index++} else {// 刚好滚动完一轮,重新来过,初始化数据top = 0index = 0scrollRef.value?.scrollTo({top: 0,})list.value = [...listSource]}}// 不断滚动requestAnimationFrame(scroll)}// 如果数据长度形成的总高度少于容器高度,不设置滚动const clientHeight = scrollRef.value?.clientHeightif (len*dataItemHeight > clientHeight) {if ((len - 1)*dataItemHeight < clientHeight) {// 如果clientHeight刚好大于len*dataItemHeight,但不满足(len+1)*dataItemHeight会出现抖动。// 解决方法:将数据复制一份listSource = listSource.concat(...Array.from({ length: 1 }, () => [...listSource]))list.value = listSourcelen = listSource.length}scroll()}
})
</script>
<style lang="scss" scoped>
.red {color: red;
}
.ellipsisText {// width: 120px;white-space: nowrap;text-overflow: ellipsis;overflow: hidden;
}
</style>
完整代码

在这里插入图片描述

<!-- 滚动展示 -->
<template><div style="height: 100%; width: 100%;"><div class="mb-3" style="font-size: 13px; color: #666;">最近30天已有<span class="red">68</span>提现成功,累计提现<span class="red">9450</span></div><!-- 滚动 --><divclass="scroll-container"ref="scrollRef"style="height: calc(100% - 32px); overflow: hidden; font-size: 13px;color: #333;"><!-- 数据list --><divv-for="(item) in list":key="item[keyText] || item.name"class="d-flex justify-space-between align-center":style="`height: ${dataItemHeight}px;`"><!-- 头像、用户名 --><div class="d-flex align-center"><v-avatar size="30" :image="item.avatar || 'https://minio.citupro.com/dev/menduner/7.png'"></v-avatar><div class="ml-2">{{ formatName(item.name) }}</div><!-- <div class="ml-2">{{ item.name }}</div> --></div><div class="d-flex" style="width: calc(100% - 65px);"><!-- 内容 --><div class="d-flex ellipsisText mx-4" style="flex: 1;"><div>推荐到</div><div class="ellipsisText ml-1" style="max-width: 100px;">{{ item.company }}</div><div class="ellipsisText ml-1" style="max-width: 60px;">{{ item.job }}</div></div><!-- 赏金 --><div>提现¥<span class="red">{{ item.money }}</span></div></div></div></div></div>
</template><script setup>
import  { onMounted, ref } from 'vue'defineOptions({name: 'publicRecruitment-bountyDisplay'})
defineProps({keyText: {type: String,default: 'id'}
})
const avatarList = ['https://img0.baidu.com/it/u=230622178,1565949306&fm=253&fmt=auto&app=138&f=JPEG?w=449&h=300','https://img0.baidu.com/it/u=1401084042,2724457850&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=726','https://img1.baidu.com/it/u=3995643348,1848098846&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=800','https://img0.baidu.com/it/u=230622178,1565949306&fm=253&fmt=auto&app=138&f=JPEG?w=449&h=300','https://img0.baidu.com/it/u=1401084042,2724457850&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=726','https://img1.baidu.com/it/u=3995643348,1848098846&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=800','https://img0.baidu.com/it/u=230622178,1565949306&fm=253&fmt=auto&app=138&f=JPEG?w=449&h=300',
]
let listSource = []
for (let index = 0; index < 68; index++) {const obj = {id: 'id' + (index+1),name: '用户' + (index+1),// name: (index+1),avatar: avatarList[index % 7],company: '某某公司' + (index+1),job: '某某职位' + (index+1),money: index*index*(100 - index) || 100,}listSource.push(obj)
}// 用户名加*号
const formatName = (name) => {if (!name.length) {return name} else if (name.length === 1) {  return name // 如果名字只有一个字,则直接返回该字  } else if (name.length === 2) {  return name.charAt(0) + '*' // 如果名字有两个字,则返回第一个字后跟一个星号  } else {  return name.charAt(0) + '**' // 如果名字有多于两个字,则返回第一个字后跟两个星号  }  
}// 滚动实现代码部分
const dataItemHeight = 40
// 容器的 dom 节点
const scrollRef = ref()
// // 模拟列表数据
// const listSource = new Array(10).fill(0).map((_, index) => ({ title: `这是一条信息${index}`}))
const list = ref([...listSource])// 记录原始数据的长度
let len = listSource.length
onMounted(() => {// 滚动的距离let top = 0// 索引let index = 0const scroll = () => {// 垂直方向滚动scrollRef.value?.scrollTo({top: top++,})if (top % dataItemHeight === 0) {// 哪一项滚不见了,就拿这一项 push 到列表中const target = list.value[index]if (target) list.value.push(target)if (index < len - 1) {// 不断递增index++} else {// 刚好滚动完一轮,重新来过,初始化数据top = 0index = 0scrollRef.value?.scrollTo({top: 0,})list.value = [...listSource]}}// 不断滚动requestAnimationFrame(scroll)}// 如果数据长度形成的总高度少于容器高度,不设置滚动const clientHeight = scrollRef.value?.clientHeightif (len*dataItemHeight > clientHeight) {if ((len - 1)*dataItemHeight < clientHeight) {// 如果clientHeight刚好大于len*dataItemHeight,但不满足(len+1)*dataItemHeight会出现抖动。// 解决方法:将数据复制一份listSource = listSource.concat(...Array.from({ length: 1 }, () => [...listSource]))list.value = listSourcelen = listSource.length}scroll()}
})
</script>
<style lang="scss" scoped>
.red {color: red;
}
.ellipsisText {// width: 120px;white-space: nowrap;text-overflow: ellipsis;overflow: hidden;
}
</style>

这篇关于【vue scrollTo 数据无限滚动 】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1081001

相关文章

MySQL数据目录迁移的完整过程

《MySQL数据目录迁移的完整过程》文章详细介绍了将MySQL数据目录迁移到新硬盘的整个过程,包括新硬盘挂载、创建新的数据目录、迁移数据(推荐使用两遍rsync方案)、修改MySQL配置文件和重启验证... 目录1,新硬盘挂载(如果有的话)2,创建新的 mysql 数据目录3,迁移 MySQL 数据(推荐两

HTML5的input标签的`type`属性值详解和代码示例

《HTML5的input标签的`type`属性值详解和代码示例》HTML5的`input`标签提供了多种`type`属性值,用于创建不同类型的输入控件,满足用户输入的多样化需求,从文本输入、密码输入、... 目录一、引言二、文本类输入类型2.1 text2.2 password2.3 textarea(严格

Python数据验证神器Pydantic库的使用和实践中的避坑指南

《Python数据验证神器Pydantic库的使用和实践中的避坑指南》Pydantic是一个用于数据验证和设置的库,可以显著简化API接口开发,文章通过一个实际案例,展示了Pydantic如何在生产环... 目录1️⃣ 崩溃时刻:当你的API接口又双叒崩了!2️⃣ 神兵天降:3行代码解决验证难题3️⃣ 深度

MySQL快速复制一张表的四种核心方法(包括表结构和数据)

《MySQL快速复制一张表的四种核心方法(包括表结构和数据)》本文详细介绍了四种复制MySQL表(结构+数据)的方法,并对每种方法进行了对比分析,适用于不同场景和数据量的复制需求,特别是针对超大表(1... 目录一、mysql 复制表(结构+数据)的 4 种核心方法(面试结构化回答)方法 1:CREATE

详解C++ 存储二进制数据容器的几种方法

《详解C++存储二进制数据容器的几种方法》本文主要介绍了详解C++存储二进制数据容器,包括std::vector、std::array、std::string、std::bitset和std::ve... 目录1.std::vector<uint8_t>(最常用)特点:适用场景:示例:2.std::arra

SpringBoot返回文件让前端下载的几种方式

《SpringBoot返回文件让前端下载的几种方式》文章介绍了开发中文件下载的两种常见解决方案,并详细描述了通过后端进行下载的原理和步骤,包括一次性读取到内存和分块写入响应输出流两种方法,此外,还提供... 目录01 背景02 一次性读取到内存,通过响应输出流输出到前端02 将文件流通过循环写入到响应输出流

SpringBoot+Vue3整合SSE实现实时消息推送功能

《SpringBoot+Vue3整合SSE实现实时消息推送功能》在日常开发中,我们经常需要实现实时消息推送的功能,这篇文章将基于SpringBoot和Vue3来简单实现一个入门级的例子,下面小编就和大... 目录前言先大概介绍下SSE后端实现(SpringBoot)前端实现(vue3)1. 数据类型定义2.

MySQL中的DELETE删除数据及注意事项

《MySQL中的DELETE删除数据及注意事项》MySQL的DELETE语句是数据库操作中不可或缺的一部分,通过合理使用索引、批量删除、避免全表删除、使用TRUNCATE、使用ORDERBY和LIMI... 目录1. 基本语法单表删除2. 高级用法使用子查询删除删除多表3. 性能优化策略使用索引批量删除避免

MySQL 数据库进阶之SQL 数据操作与子查询操作大全

《MySQL数据库进阶之SQL数据操作与子查询操作大全》本文详细介绍了SQL中的子查询、数据添加(INSERT)、数据修改(UPDATE)和数据删除(DELETE、TRUNCATE、DROP)操作... 目录一、子查询:嵌套在查询中的查询1.1 子查询的基本语法1.2 子查询的实战示例二、数据添加:INSE

Linux服务器数据盘移除并重新挂载的全过程

《Linux服务器数据盘移除并重新挂载的全过程》:本文主要介绍在Linux服务器上移除并重新挂载数据盘的整个过程,分为三大步:卸载文件系统、分离磁盘和重新挂载,每一步都有详细的步骤和注意事项,确保... 目录引言第一步:卸载文件系统第二步:分离磁盘第三步:重新挂载引言在 linux 服务器上移除并重新挂p