Skip to content

vxe-table vxe-list 滚动到底部存在留白不触发刷新

源码

html
<vxe-list
  :height="height"
  :data="currentDataList"
  :scroll-y="{
      oSize: 0,
      gt: 40,
      enabled: true,
      sItem: '.my-list .my-list-row'
    }"
  :auto-resize="false"
  :sync-resize="dataList"
  :style="{width: `calc(${tableStyles} - 6px)`}"
  ref="multipleTableRef"
  class="my-list mytable-scrollbar"
>
  <!-- sItem: '.my-list .my-list-row'
    这行代码很关键,vxe-table 会根据这个元素来计算当前的行高
    源码在  node_modules\vxe-table\es\list\src\list.js 的 computeScrollLoad 方法
    -->
</vxe-list>

原因

  1. 通过查看源码 发现是 如果不指定 sItem 会默认获取第一个元素作为当前行的行高
  2. 然而我的第一个元素是一个 标题,不是真实要滚动的数据的行高,导致行高计算错误,导致 vxe-table 滚动的时候错误

源码在 node_modules\vxe-table\es\list\src\list.js 的 computeScrollLoad 方法

Details
js
var computeScrollLoad = function () {
  return nextTick().then(function () {
    var scrollYLoad = reactData.scrollYLoad;
    var scrollYStore = internalData.scrollYStore;
    var virtualBodyElem = refVirtualBody.value;
    var sYOpts = computeSYOpts.value;
    var rowHeight = 0;
    var firstItemElem;
    if (virtualBodyElem) {
      if (sYOpts.sItem) {
        firstItemElem = virtualBodyElem.querySelector(sYOpts.sItem);
      }
      if (!firstItemElem) {
        firstItemElem = virtualBodyElem.children[0];
      }
    }
    if (firstItemElem) {
      rowHeight = firstItemElem.offsetHeight;
    }
    rowHeight = Math.max(20, rowHeight);
    scrollYStore.rowHeight = rowHeight;
    // 计算 Y 逻辑
    if (scrollYLoad) {
      var scrollBodyElem = refVirtualWrapper.value;
      var visibleYSize = Math.max(
        8,
        Math.ceil(scrollBodyElem.clientHeight / rowHeight)
      );
      var offsetYSize = sYOpts.oSize
        ? XEUtils.toNumber(sYOpts.oSize)
        : browse.edge
        ? 10
        : 0;
      scrollYStore.offsetSize = offsetYSize;
      scrollYStore.visibleSize = visibleYSize;
      scrollYStore.endIndex = Math.max(
        scrollYStore.startIndex,
        visibleYSize + offsetYSize,
        scrollYStore.endIndex
      );
      updateYData();
    } else {
      updateYSpace();
    }
    reactData.rowHeight = rowHeight;
  });
};

解决办法

指定 sItem 的类名为真正要滚动的行

修改前

js
:scroll-y="{ oSize: 0, gt: 40, enabled: true }"

修改后

js
:scroll-y="{ oSize: 0, gt: 40, enabled: true, sItem: '.my-list .my-list-row' }"

如何开发环境调试 vxe-table

  1. 找到 安装的包的 package.json node_modules\vxe-table\package.json

alt text

json
{
  "main": "lib/index.common.js", // 指定了包的主入口文件,适用于使用 CommonJS 模块系统的环境(如 Node.js),通过 require() 加载。
  "module": "es/index.esm.js", // 指定了使用 ECMAScript 模块系统的入口文件,适用于支持 ES2015+ 模块的现代前端构建工具(如 Webpack, Rollup)。
  "unpkg": "lib/index.umd.js" // 指定了通过 UNPKG CDN 加载时使用的 UMD 格式文件,适用于在浏览器中直接通过 <script> 标签加载。
}
  1. 修改 vxe-table 包的引入方式 import VXETable from 'vxe-table' 改成 import VXETable from "vxe-table/es/index.esm.js";
js
import VXETable from "vxe-table/es/index.esm.js";
// import VXETable from 'vxe-table';
import "vxe-table/lib/style.css";
  1. 找到你要修改的组件名称 vxe-list 它的源码最终在 node_modules\vxe-table\es\list\src\list.js 文件

  2. 修改这个组件,增加一些 console.log

  3. 刷新页面这个时候就可以看到 你新加入的日志了