vue实现虚拟表格 一看就懂

于常见的触底懒加载的优劣对比

优势:

  1. 滚动平滑性: 虚拟列表可以在滚动时实时渲染可见区域内的数据,保持滚动的平滑性,不会因为数据量大而导致滚动卡顿。
  2. 性能优化: 虚拟列表能够有效减少渲染的 DOM 元素数量,从而提高页面的性能和响应速度。
  3. 快速渲染: 虚拟列表根据滚动位置计算需要渲染的数据,渲染速度较快,可以更快地展示数据。

劣势:

  1. 不适用动态数据: 虚拟列表适用于静态数据或数据变化不频繁的情况,对于动态变化的数据需要额外的处理。

效果展示

 

 

创建一个父级div

 

主要添加下面两个属性,其他样式随便

overflow: auto;
position: relative;

 

然后添加子级div仅用于撑开父级,高度是根据数据量来的,我这里模拟1w条数据 高度55w px 

 

 然后再添加 存放数据的盒子 使用绝对定位

数据展示

 

实现逻辑

滚动实际是撑开的div实现的,与数据展示没有关系,展示数据的box盒子 使用绝对定位和top 让它一直固定在能看到的位置

数据的展示:

        上图中可以看到,第一跳数据已经滚动到了顶部以外,当它超出一个行高的时候 它就会被删除替换成地二条数据 比如 开始是 0--9 当滑动的时候 他就变成了 1 -- 10 然后top下移一个行高。

        在下边我们看到除了能看到的22 在dom里面还有24 这个就是防止下滑太快导致出现空白区域的

 完整代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .content{
            width: 500px;
            height: 550px;
            border: #2d9f75 1px solid;
            overflow: auto;
            margin: 0 auto;
            position: relative;
        }
        .item-box{
            position: absolute;
            width: 100%;
            top: 0; /* Add top: 0; */
            left: 0; /* Add left: 0; */
        }
        .item-li{
            width: 100%;
            text-align: center;
            height: 55px;
            line-height: 55px;
            border: antiquewhite 0.5px solid;
        }
    </style>
</head>
<body>

<div id="app">
    <div class="content" ref="contentRef" @scroll="handleScroll">
<!--        根据总条数和 每行的高度 计算出 高度,次div 只用于撑开父级 出现滚动条-->
        <div :style="{'height':`${total * this.lineHeight}px`}"></div>
<!--        用于绝对定位,展示可视窗口数据-->
        <div class="item-box">
            <div v-for="(item,index) in visibleList" :key="index" class="item-li">{{item.name}}</div>
        
        </div>
    
    </div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            total:10000,// 总条数 ,也可根据list数组长度计算
            lineHeight:55,// 每一行高度
            bufferSize:2,// 缓冲数
            list:[],// 原数组
            visibleList: [],// for循环 展示的数组
        },
        methods:{
            updateVisibleList() {
                // 获取父级div dom计算距离顶部距离
                const content = this.$refs.contentRef; 
                // 获取浮动div 设置top值
                const itemBox = this.$el.querySelector('.item-box');
                // content.scrollTop 是当前滚动条距离顶部的距离 / this.lineHeight(每行高度) 得出可视窗口内 展示的数据开始下标
                const startIndex = Math.floor(content.scrollTop / this.lineHeight);
                /* content.clientHeight 可视窗口区域高度用于计算 窗口内展示多少行数据 ,
                 bufferSize缓冲数 在原数据上多显示两行 防止快速滑动的时候出现白色区域*/
                const endIndex = startIndex + Math.ceil(content.clientHeight / this.lineHeight) + this.bufferSize;
                // list 是1万条数据,visibleList才是正常for循环的数据,需要根据下标赋值
                this.visibleList = this.list.slice(startIndex, endIndex);
                // 设置绝对定位top 使得 itemBox 始终在我们的视线内
                itemBox.style.top = `${startIndex * this.lineHeight}px`;
            },
            handleScroll(){
                this.updateVisibleList();
            }
        },
        mounted(){
            // 构造1万条数据 一般来说是从后端请求的数据
            for (let i = 0; i < this.total;i++) {
                this.list.push({
                    name:'name'+i
                })
            }
            this.updateVisibleList();
        }
    })
</script>
</body>
</html>

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现虚拟表格,需要结合vue-virtual-scroller和eltable的功能。以下是简单的实现步骤: 1. 安装vue-virtual-scroller和element-ui ```bash npm install vue-virtual-scroller element-ui ``` 2. 在Vue组件中导入和注册vue-virtual-scroller和eltable组件 ```javascript import { VirtualScroller } from 'vue-virtual-scroller' import { Table, TableColumn } from 'element-ui' export default { components: { VirtualScroller, Table, TableColumn }, // ... } ``` 3. 在template中使用vue-virtual-scroller和eltable组件 ```html <template> <virtual-scroller :items="items" :item-size="50" class="table-virtual-scroller"> <el-table :data="items" class="table-body" :row-class-name="tableRowClassName"> <el-table-column prop="name" label="姓名"></el-table-column> <el-table-column prop="age" label="年龄"></el-table-column> <el-table-column prop="address" label="地址"></el-table-column> </el-table> </virtual-scroller> </template> ``` 4. 在script中设置数据源和样式 ```javascript export default { data() { return { items: [] // 设置数据源 } }, mounted() { // 获取数据并更新items this.items = getData() // 设置虚拟列表容器的高度 const windowHeight = window.innerHeight const tableHeaderHeight = 40 // 表头高度 const tableRowHeight = 50 // 行高 const tableBodyHeight = this.items.length * tableRowHeight // 表格体高度 const tableVirtualScrollerHeight = windowHeight - tableHeaderHeight // 表格虚拟容器高度 document.querySelector('.table-virtual-scroller').style.height = tableVirtualScrollerHeight + 'px' // 设置表格体高度 document.querySelector('.table-body__wrapper').style.height = tableBodyHeight + 'px' }, methods: { tableRowClassName({ rowIndex }) { // 自定义行样式 return rowIndex % 2 === 0 ? 'table-row-even' : 'table-row-odd' } } } ``` 5. 样式设置 ```css /* 虚拟列表容器 */ .table-virtual-scroller { overflow-y: auto; position: relative; } /* 表格体 */ .table-body__wrapper { overflow: hidden; } /* 奇数行样式 */ .table-row-odd { background-color: #f9f9f9; } /* 偶数行样式 */ .table-row-even { background-color: #e6f7ff; } ``` 以上是一个简单的虚拟表格实现方法,您可以根据自己的需求进行样式、数据处理等方面的修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值