• vue 虚拟表格方案


    支持xy虚拟滚动的表格方案

    表头固定

    将每个th 设置为position:sticky;top:0;即可完成表头固定操作。注意设置z-index

    为什么不直接设置thead sticky

    兼容性,chrome> 90 (根据 caniuse:sticky

    基本html结构

    <div style="overflow:auto;">
        <table style="width:100%">
            <thead>
                <tr>
                    <th style="position:sticky;top:0;">th>
                tr>
            thead>
            <tbody>
                <tr>
                    <td style="position:sticky;left:0">td>
                tr>
            tbody>
        table>
    div>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    单元格border

    使用background-image: linear-gradient,渐变1px,绘制border,防止border影响布局。(大量使用linear-gradient性能影响有待考究)

    vxe-table也采用类似的方式:使用linear-gradient绘制纯色背景,但vxe-table 使用background-size 控制背景为1px;

    y轴虚拟滚动方案

    总高度

    计算总高度。使用width:1px;height:总高度;position:absolute; div元素。以此撑开容器,得到滚动条
    使用 可视区上距离 + 可视区下距离+ 可视区高度 计算出总高度。

    可视区位置控制

    可以用padding, margin, position:relative, transform:translate

    这里使用两个 ,设置min-height控制可视区顶部距离和底部距离。

    为什么用tr控制

    在新版浏览器中,渲染不阻塞滚动条运动。若滚动过快,会导致表头消失。(因为整个table都在不可见区,此时sticky就不生效)

    <div style="overflow:auto;">
        <table style="width:100%">
            <thead>
                <tr>
                    <th style="position:sticky;top:0;">th>
                tr>
            thead>
            <tbody>
            	
                <tr style="min-height:0px"><tr>
                
                <tr>
                    <td style="position:sticky;left:0">td>
                tr>
                
                 <tr style="min-height:100px"><tr>
            tbody>
        table>
    div>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    高度计算

    • 通过scrollTop ,行高计算列表渲染开始位置startIndex。
    • 通过容器高度/行高,计算页大小pageSize。
    • 结束位置endIndex= startIndex + pageSize
    • vue computed 创建数组切片(源数组.slice(startIndex,pageSize))
    • 使父容器出现滚动条,各种方式撑开父容器,使scrollHeight为所有数据条数x行高。(padding/margin/绝对定位元素/tr高度…)
    • 滚动滚动条时,实时调整表格的位置可见,不要被滚动到上面看不见了。

    后处理

    虚拟滚动时,表格中不要因为换行导致行高变化。
    endIndex 要+1,防止特殊滚动时,表格最下方空白。
    endIndex 大于数据总量时的特殊处理。

    x轴虚拟滚动方案

    总宽度

    计算每一个列配置中的width/min-width/max-width。为确保计算的宽度不变,这里列配置中min-width === max-width。(后期使min-width = width?)

    可视区定位

    同y轴虚拟滚动方案。

    这里用 控制位置。

    由于在表头最前方加了 一个 ,因此在tbody 每行前都要加一个空td。防止错位。

    <div style="overflow:auto;">
        <table style="width:100%">
            <thead>
                <tr>
                	
                    <th style="min-width:0px;">th>
                    <th style="position:sticky;top:0;">th>
                    
                    <th style="min-width:100px;">th>
                tr>
            thead>
            <tbody>
                <tr style="min-height:0px"><tr>
                <tr>
                    <td>td>
                    <td style="position:sticky;left:0">td>
                tr>
                 <tr style="min-height:100px"><tr>
            tbody>
        table>
    div>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    列固定

    采用sticky(高版本浏览器)

    在84版本,当横向滚动距离超过父元素宽度时,会导致sticky失效。
    横向虚拟滚动在高版本浏览器中会有问题。也是滚动条不阻塞渲染导致,固定列跳动。

    固定列用transform:translateX()实现。新版浏览器可能在滚动时会有跳动的情况。

    在84版本(高版本未尝试),横向滚动条移动到最右侧时,减少列数量,导致横向滚动条长度不重置。(猜测浏览器不重排transform图层)此时变动一下表格样式即可触发重排。

    使用position:relative;配合left。(性能较sticky差)

    注意设置z-index 左上角表头最大。其次为表头和固定列,其次为表体。

    x轴虚拟滚动+列固定

    虚拟滚动裁剪数组中,在startIndex前的固定列都需要保留。
    计算虚拟滚动可视区左侧偏移量也需要调整
    通过横向滚动scrollLeft 计算startIndex的算法也需要调整

    表头拖拽排序

    原生 draggable="true" 实现

    优化

    Object.freeze()

    高亮行/单元格

    高亮行/单元格,渐暗。非虚拟滚动时,只要加上css @keyframe 关键帧动画,配合setTimeout 动画结束后移除class即可。
    虚拟滚动由于元素会增加和移除。在滚动时,会导致可视区外的元素动画效果有问题。
    在虚拟滚动时,需要手动计算行的背景。使用d3.interpolate 库来计算颜色过渡。通过window.requestAnimation 循环更新每一行的颜色。

  • 相关阅读:
    migration 与navicat
    [附源码]java毕业设计智慧教学平台
    jenkins常见问题
    0816(032天 线程/进程03 一点细节+线程池)
    【Unity3D】动态路径特效
    PPTP和L2TP哪种好?
    数字IC设计全流程
    Java 继承(extends)
    【24】c++设计模式——>代理模式
    java毕业设计开题报告springboot+mysql实现的电影资讯网站|影视[包运行成功]
  • 原文地址:https://blog.csdn.net/qq_35459724/article/details/127690889