Vue+TS开发定长虚拟列表

news2024/11/19 21:18:16

1.定长虚拟列表

  1. 定义:虚拟列表也有叫无限滚动的,创建一个滚动列表来渲染大量数据

  2. 使用场景有大量数据需要渲染时。

  3. **解决了什么问题?**大量数据需要渲染,例如Vue传统使用V-for遍历会创建大量Node节点,对于内存和渲染时间的占用都是非常大的。

  4. 怎么做?

    1. 虽然数据量很大但是我们要展示给用户的并不是全部数据,因此我们只需要根据每个元素高度和视口高度渲染元素即可。
    2. 然后监听滚动,当滚动时动态切换数据
    3. 将内容盒子随着滚动进行Y轴的偏移
  5. HTML和css结构

    1. <div class="container" :style="container_style">
          <!-- 容器盒子-》监听该容器的滚动事件 -->
          <div class="scroll_container" ref="scroll_ref">
            <!-- 撑起盒子高度 -->
            <div class="pillar" ></div>
             <!-- 内容列表用来渲染数据的盒子 -->
            <div class="items" ref="items_ref" >
              <div :style="item_style" v-for="item in renderData" key="item" class="item">{{ item }}</div>
            </div>
          </div>
        </div>
      
    2. css使用动态属性去绑定结构很清晰,可扩展性很强
      <style lang="scss" scoped>
       .container{
        width: v-bind('props.style.width');
        height: v-bind('props.style.height');
        background: v-bind('props.style.background');
        .scroll_container::-webkit-scrollbar {
          width: 10px; /* 滚动条的宽度 */
          background-color: #f5f5f5; /* 滚动条的背景颜色 */
        }
        .scroll_container::-webkit-scrollbar-thumb {
          background-color: greenyellow; /* 滚动条拖动块的颜色 */
        }
        .scroll_container{
          position: relative;
          overflow: auto;
          -webkit-overflow-scrolling:touch;
          width: 100%;
          height: 100%;
          .pillar{
            position: absolute;
            right: 0;
            left: 0;
            top: 0;
            z-index: -1;
            height: v-bind('scroll_height');
          } 
          .items{
            height: 100%;
            z-index: 10;
            top: 0;
            left: 0;
            right: 0;
            position: absolute;
            box-sizing: border-box;
            .item{
              width: 100%;
              line-height: calc(v-bind('props.item_height') * 1px);
              height: calc(v-bind('props.item_height') * 1px);
              box-sizing: border-box;
            }
          }
        }
       }
      </style>
      
  6. Vue核心部分

    1. interface IVirtualListPropsStyle {
          width: string
          height: string
          background: string
      }
      
      interface IVirtualListProps {
        style?: IVirtualListPropsStyle
        data: any[],
        show_size?: number
        item_height?: number,
        item_style?: Record<string, any>
        container_style?:Record<string, any>
      }
      
      
      const props = withDefaults(defineProps<IVirtualListProps>(), {
        style: () => {
          return {
            width: '400px',
            height: '200px',
            background:'skyblue'
          }
        },
        data: ()=>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
        show_size: 5,
        item_height:40
      })
      const scroll_ref = ref<HTMLElement|null>(null)
      const items_ref = ref<HTMLElement|null>(null)
      
      const {
        scroll_height,
        renderData
      } = useVirtualList(props,scroll_ref as Ref<HTMLElement>,items_ref as Ref<HTMLElement>)
      
      
    2. hooks-》useVirtualLit

      import { computed, onMounted, ref, type Ref } from "vue"
      export default (props: IVirtualListProps, scroll_ref: Ref<HTMLElement> | null, items_ref: Ref<HTMLElement> | null) => {
          const scrollTop = ref(0)
          // 定高虚拟列表的当前页展示个数 = 内容容器高度 / 单个内容高度
          const show_size = computed(() => Math.ceil(parseInt(props.style.height) / props.item_height))
          // 总高度 每个数据的高度×总数据个数
          const scroll_height = computed(() => {
              if (props.data.length === 0) {
                  console.warn(`Not received props.data`)
                  return 0
              }
              return (props.data.length - 1) * props.item_height + 'px'
          })
          // 切片的起始和结束索引
          const start_index = ref(0)
          const end_index = ref(show_size.value)
          // 切片渲染数据
          const renderData = computed(() => props.data.slice(start_index.value, end_index.value))
      
          onMounted(() => {
              scroll_ref!.value.addEventListener('scroll', (e: Event) => {
                  // show_size.value * props.item_height -》从滚动开始计算
                  scrollTop.value = (e.target as HTMLElement).scrollTop + show_size.value * props.item_height
                  // 滚动改变索引的偏置
                  const bias = Math.ceil(scrollTop.value / props.item_height)
                  start_index.value += bias - end_index.value
                  end_index.value = end_index.value + (bias - end_index.value)
                  // 内容容器Y的偏移量
                  items_ref!.value.style.transform = `translateY(${(e.target as HTMLElement).scrollTop}px)`
              })
          })
          return {
              scroll_height,
              renderData
          }
      }
      
  7. 结果展示:内容的DOM节点始终只有五个但是渲染的数据很大
    在这里插入图片描述
    体验直接下载 pnpm install fancy_virtual_list 即可,具体功能可看md

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/495739.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【AI 导航网站】为了更好的收集 AI 资源,我开发了一个 AI 导航网站

AI 导航网站 目前 AI 应用正呈迸发式增长&#xff0c;然而一个人获取资源的途径有限&#xff0c;对于目前存在的AI工具不能很好的收集总结&#xff0c;所以基于此&#xff0c;我开发了这个一个AI导航网站&#xff0c;希望通过它&#xff0c;收集出目前存在的热门的AI应用&…

(一)Springcloud-OpenFeign原理之集成改造原生Openfeign与简单使用

文章目录 1.和原生Openfeign的关系2.Springcloud-Openfeign的改造2.1 改造目标2.2 改造内容2.2.1 集成到Spring2.2.2 替换构造组件 2.3 初步集成使用2.4 支持的扩展点 文章将会介绍Springcloud-Openfeign对原生Openfeign的改造原因及方式&#xff0c;最后提供简单的使用案例及扩…

实验一 进程管理与进程同步

实验一 进程管理与进程同步 实验目的&#xff1a; 了解进程管理的实现方法&#xff0c;理解和掌握处理进程同步问题的方法。 实验内容&#xff1a; 实现银行家算法、进程调度过程的模拟、读者-写者问题的写者优先算法。 实验步骤&#xff1a; 1.银行家算法流程图 &…

Springboot +Flowable,任务认领和回退(一)

一.简介 有的时候&#xff0c;一个任务节点会存在多个候选人&#xff0c;例如&#xff1a;张三提交一个任务&#xff0c;这个任务即可以由李四处理&#xff0c;又可以由王五处理&#xff0c;那么针对这种多个任务候选人的情况&#xff0c;该如何处理&#xff1f; 二.绘制流程…

Java线程池及其实现原理

线程池概述 线程池&#xff08;Thread Pool&#xff09;是一种基于池化思想管理线程的工具&#xff0c;经常出现在多线程服务器中&#xff0c;如MySQL。 线程过多会带来额外的开销&#xff0c;其中包括创建销毁线程的开销、调度线程的开销等等&#xff0c;同时也降低了计算机…

Spark任务提交流程

1. yarn-client Driver在任务提交的本地机器上运行&#xff0c;Driver启动后会和ResourceManager通讯&#xff0c;申请启动ApplicationMaster; 随后ResourceManager分配Container&#xff0c;在合适的NodeManager上启动ApplicationMaster&#xff0c;此时的ApplicationMaster的…

华为网络设备+WinRadius 实现用户统一管理设备

一、直接贴配置 ###配置VTY用户界面所支持的协议、验证方式 user-interface vty 0 4 protocol inbound telnet authentication-mode aaa quit ###配置RADIUS认证 ###&#xff08;1&#xff09;配置RADIUS服务器模板&#xff0c;指定服务器的IP地址与端口号、共享密钥 radius-s…

Supervisor离线安装(python3.7.8)

Background supervisor是用Python语言开发的一套通用的进程管理程序&#xff0c;可以将一个普通的命令行进程变为后台daemon&#xff0c;并监控进程状态&#xff0c;异常退出时可以自动拉起&#xff1b;可在大多数unix系统上使用&#xff0c;不能在windows上运行&#xff1b;目…

学Python常逛的10个网站

这里写目录标题 一、Python官方文档二、牛客网三、Github四、w3school五、Chatgpt六、kaggle七、realpython八、medium九、stackoverflow十、geeksforgeeks 一、Python官方文档 最全面的Python学习网站非官方文档莫属&#xff0c;它不仅提供了下载安装教程、基础语法教程、标准…

编写UDP版本的客户-服务器程序(echo server 和 echo client)

目录 前言概要 关于数据报流的关键方法签名 UDP协议传输案例 服务端&#xff08;接收端&#xff09; 服务端完整代码 客户端(发送端) 客户端完整代码 创作不易多多支持&#x1f636;‍&#x1f32b;️&#x1f618; 前言概要 我们首先来了解一下, 什么是网络编程. 网络编程…

认识系统总线

目录 一、总线的基本概念 1.总线的定义 二、总线的分类 1.片内总线 2.系统总线 2.1数据总线 2.2地址总线 2.3控制总线 3.通信总线(通信总线) 三、总线特性及性能指标 1.总线特征 2.性能标准 2.1总线的传输周期(总线周期) 2.2总线时钟周期 2.3总线的工作频率 2.4…

vim编辑器命令模式——撤销与时间旅行

Vi介绍 Vi 编辑器是所有 Unix 及 Linux 系统下标准的编辑器&#xff0c;类似于 windows 系统下的 notepad &#xff08;记事本&#xff09;编辑器&#xff0c;由于在 Unix 及 Linux 系统的任何版本&#xff0c;Vi 编辑器是完全相同的&#xff0c;因此可以在其他任何介绍 vi 的地…

小红书数据,如何在垂类赛道中脱颖而出!

导语 近年来&#xff0c;泛娱乐内容在小红书平台盛行&#xff0c;面临流量见顶的情况。这时候&#xff0c;垂类账号的优势就显现出来&#xff0c;不仅可以规避激烈的竞争&#xff0c;还能去获取更精准的流量。 作为一个经久不衰的创作方向&#xff0c;美食赛道分化出教程、测…

webpack plugin原理以及自定义plugin

通过插件我们可以拓展webpack&#xff0c;加入自定义的构建行为&#xff0c;使webpack可以执行更广泛的任务。 plugin工作原理&#xff1a; webpack工作就像是生产流水线&#xff0c;要通过一系列处理流程后才能将源文件转为输出结果&#xff0c;在不同阶段做不同的事&#x…

核磁机器学习 | 基于机器学习的fMRI分类

导读 本文通过提取最显著的特征&#xff0c;将大脑图像分类为正常和异常&#xff0c;并对大脑各种状态的磁共振成像(MRI)进行了研究。本文描述了一种基于小波变换的方法&#xff0c;首先对图像进行分解&#xff0c;然后使用各种特征选择算法从MRI图像中提取最显著的大脑特征。…

[Netty] 面试问题 1 (十八)

文章目录 1.Netty的特点2.Netty应用场景3. Netty核心组件4.Netty的线程模型5. EventloopGroup和EventLoop6.Netty 的零拷贝7.Netty 长连接和心跳机制8.Netty 服务端和客户端的启动过程9.Netty 的 Channel 和 EventLoop10.Netty 的 ChannelPipeline11.Netty 中的 ByteBuf12.Nett…

数据分析01——Anaconda安装/Anaconda中的pip换源/jupyter配置

0、前言&#xff1a; 数据分析三大模块知识&#xff1a;numpy&#xff08;数组计算&#xff09;、pandas&#xff08;基于numpy开发&#xff0c;用于数据清洗和数据分析&#xff09;、matplotlib&#xff08;实现数据可视化&#xff09; 1、Anaconda安装&#xff1a; 安装Ana…

Spring常见面试题总结(2023最新版)

文章目录 1、谈谈你对Spring的理解&#xff1f;1.1 发展历程1.2 Spirng的组成1.3 Spring的好处 2、Autowired和Resource的区别2.1 共同点&#xff1a;2.2 Autowired2.3 Resource2.3.1 Resource的装配顺序 3、Spring常用注解3.1、给容器中注入组件3.1.1 包扫描组件标注注解3.1.2…

Faster-RCNN跑自己的数据集(详细过程)FPN学习

1、下载b站 &#xff1a;霹雳吧啦Wz 的代码 github链接&#xff1a;https://github.com/WZMIAOMIAO/deep-learning-for-image-processing 对应视频链接&#xff1a;2-自定义DataSet_哔哩哔哩_bilibili 2、配置环境&#xff0c;安装相应的包。 或者如果有报错可以直接更新重新…

数据结构之栈的详解

文章目录 一.什么是栈二. 栈的使用2.1栈的基本操作2.2 栈的基本使用 三.栈的实现3.1 数组实现栈的方式3.2 链式栈的实现 四.栈的应用4.1 括号匹配4.2 逆波兰表达式求值什么是逆波兰表达式 4.3 出栈入栈次序匹配4.4 最小栈五.总结 一.什么是栈 栈是一种先入后出(FILO)的线性表数…