关于有固定列的el-table 在滚动加载的时候固定列的行和非固定列的行对不齐有几px的错位且doLayout不生效有对应的解决方案...

关于有固定列的el-table 在滚动加载的时候固定列的行和非固定列的行对不齐有几px的错位且doLayout不生效有对应的解决方案:

在滚动结束时通过对比固定列table和非固定列table强制dom操作

// @ts-ignore
import elInfiniteScroll from "element-ui/lib/infinite-scroll";

const elScope = "ElInfiniteScroll";
const msgTitle = `[el-table-infinite-scroll]: `;
const elTableScrollWrapperClass = ".el-table__body-wrapper";

// 处理滚动过程中固定列的行和非固定列的行不对齐的情况
function handleException( el: HTMLElement , scrollElem: HTMLElement, addEventLister: boolean = true) {
  let scrollTimer: any = null;
  function scrollCallback() {
    clearTimeout(scrollTimer);
    scrollTimer = setTimeout(() => {
      const scrollFixedElem = el.querySelector(".el-table__fixed-body-wrapper") as any;
      if (!scrollFixedElem) {
        return;
      }
      if (scrollFixedElem.scrollTop !== scrollElem.scrollTop) {
        scrollFixedElem.scrollTop = scrollElem.scrollTop;
      }
      const barHeight = 8;
      const tableHeaderHeight = 50;
      if (scrollElem.scrollHeight + barHeight === scrollElem.scrollTop + scrollElem.offsetHeight) {
        scrollFixedElem.style.top = tableHeaderHeight - barHeight + "px";
      } else {
        scrollFixedElem.style.top = tableHeaderHeight + "px";
      }
    }, 0);
  }
  if (addEventLister) {
    scrollElem.addEventListener("scroll", scrollCallback);
  } else {
    scrollElem.removeEventListener("scroll", scrollCallback);
  }
}

/**
 * 同步 el-infinite-scroll 的配置项
 * @param sourceVNode
 * @param sourceElem
 * @param targetElem
 */
function asyncElOptions(sourceVNode: any, sourceElem: any, targetElem: any) {
  let value;
  ["disabled", "delay", "immediate"].forEach((name: string) => {
    name = "infinite-scroll-" + name;
    value = sourceElem.getAttribute(name);
    if (value !== null) {
      targetElem.setAttribute(name, value);
    }
  });

  // fix: windows/chrome 的 scrollTop + clientHeight 与 scrollHeight 不一致的 BUG
  const name = "infinite-scroll-distance";
  value = sourceElem.getAttribute(name);
  targetElem.setAttribute(name, value < 1 ? 1 : value);
}

export default {
  inserted(el: any, binding: any, vnode: any, oldVnode: any) {
    // 获取 table 中的滚动层
    const scrollElem = el.querySelector(elTableScrollWrapperClass);

    // 如果没找到元素,返回错误
    if (!scrollElem) {
      throw `${msgTitle}找不到 ${elTableScrollWrapperClass} 容器`;
    }

    // 设置自动滚动
    scrollElem.style.overflowY = "auto";

    // dom 渲染后
    setTimeout(() => {
      // if (!el.style.height) {
      //   scrollElem.style.height = "400px";
      //   console.warn(
      //     `${msgTitle}请尽量设置 el-table 的高度,可以设置为 auto/100%(自适应高度),未设置会取 400px 的默认值(不然会导致一直加载)`
      //   );
      // }

      asyncElOptions(vnode, el, scrollElem);

      // 绑定 infinite-scroll
      elInfiniteScroll.inserted(scrollElem, binding, vnode, oldVnode);

      // 将子集的引用放入 el 上,用于 unbind 中销毁事件
      el[elScope] = scrollElem[elScope];
    }, 0);

    // 处理滚动过程中固定列的行和非固定列的行不对齐的情况
    handleException( el, scrollElem);
  },
  componentUpdated(el: any, binding: any, vnode: any) {
    asyncElOptions(vnode, el, el.querySelector(elTableScrollWrapperClass));
  },
  unbind: (el: any) => {
    try {
      const scrollElem = el.querySelector(elTableScrollWrapperClass);
      handleException( el, scrollElem, false);
      elInfiniteScroll.unbind();
    } catch (e) {
    }
  },
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue3中的`el-table`组件是Element UI库中的表格组件,它支持滚动数据(通常称为无限滚动或懒)。当用户滚动到表格底部时,如果还有更多数据未展示,滚动功能会自动向服务器请求下一页的数据并更新表格内容。 以下是实现滚动的基本步骤: 1. 配置`el-table`:设置`scroll-y`属性为true,开启垂直滚动,并给需要监听滚动事件的元素添`@scroll`事件处理器。 ```html <template> <el-table :data="tableData" :height="tableHeight" @scroll="loadMore"> <!-- ...表头... --> </el-table> </template> <script> export default { data() { return { tableData: [], // 初始数据 tableHeight: '400px', // 设置固定高度或动态计算 page: 1, // 当前页数 pageSize: 10, // 每页显示的数 }; }, methods: { loadMore() { if (this.tableBottomReached()) { // 判断是否到达底部 this.fetchMoreData(); // 发送请求更多数据 } }, fetchMoreData() { this.page++; // 一,请求下一页 // 这里发送异步请求获取更多数据,例如: axios.get('api/data?page=' + this.page) .then(response => { const newData = response.data; // 新的数据 // 将新数据合并到已有数据中 this.tableData.push(...newData); }) .catch(error => { console.error('Failed to load more data:', error); }); }, tableBottomReached() { // 返回滚动条距离文档底部的距离小于等于某个阈值时的布尔值 const scrollEl = document.querySelector('.el-table'); const clientHeight = scrollEl.clientHeight; const scrollTop = scrollEl.scrollTop + clientHeight; const scrollHeight = scrollEl.scrollHeight; return scrollTop >= scrollHeight - clientHeight; } }, }; </script> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值