Intersection Observer API 交叉观察器 API vue3 antd table 滚动加载 使用过程

发布时间 2023-06-03 11:33:45作者: 凿壁偷光,集思广益

需求:表格滚动加载

做法:
步骤一:给表格最后一行添加特定标识,类名或者id等

组件库 https://www.antdv.com/components/table-cn#API
webApi https://developer.mozilla.org/zh-CN/docs/Web/API/Intersection_Observer_API
组件名 table
添加类名的组件方法 rowClassName
使用例子:

:rowClassName="(record):any => (if(datasource.length===record.index:'begin_load_anchor':''))"

步骤二:使用web api

//观察器对象
//包含 被观察对象的父容器 root  容器外边距 rootMargin 以及被观察者出现在观察者显示的大小 threshold


let options = {
  root: document.querySelector('#scrollArea'),
  rootMargin: '0px',
  threshold: 1.0
}
//观察者实例
let observer = new IntersectionObserver(callback, options);
// 节流
export function debounce<Func extends (...args: any[]) => any>(
  func: Func,
  wait: number,
  immediate = false
): (...args: Parameters<Func>) => void {
  let timeout: any | ReturnType<typeof setTimeout>;

  return function executedFunction(this: any, ...args: Parameters<Func>) {
    const later = () => {
      timeout = null;
      if (!immediate) func.apply(this, args);
    };

    const callNow = immediate && !timeout;
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);

    if (callNow) func.apply(this, args);
  };
}
//做一个节流
 const debouncedShowItem = debounce(beginLoadAnchor, 100);
let target = document.querySelector('#listItem');
observer.observe(target);
export async function useLazyLoading(props: ComputedRef<BasicTableProps>, destroy?: boolean) {
  const ele = props?.value?.columnsKey
    ? `.begin_load_anchor_${props.value.columnsKey}`
    : '.begin_load_anchor';
  const beginLoad: any = document.querySelector(ele);
  const body = props?.value?.columnsKey
    ? `.ant-table-body_${props.value.columnsKey}`
    : '.ant-table-body';
  const root: any = document.querySelector(body);
  const begin_load_anchor = {
    root,
    rootMargin: '0px',
    threshold: 0.2,
  };

  function beginLoadAnchor(entries) {
    if (isFunction(props?.value?.loadAnchor) && entries[0].isIntersecting) {
      props?.value?.loadAnchor();
    }
  }
  const debouncedShowItem = debounce(beginLoadAnchor, 100);

  const observer_load = new IntersectionObserver(debouncedShowItem, begin_load_anchor);
  const callback = () => {
    isShowBackTop.value = root.scrollTop > 300;
  };

  if (root instanceof Element) {
    root.addEventListener('scroll', callback, true);
  }

  if (beginLoad instanceof Element) {
    observer_load.observe(beginLoad);
  }

  if (root instanceof Element && beginLoad instanceof Element && destroy) {
    isShowBackTop.value = false;
    observer_load.disconnect();
    root.removeEventListener('scroll', debouncedShowItem);
  }
}