vue + element table下拉加载数据

846 阅读1分钟

需求:不使用分页加载表格,但是一次性加载数据,太过消耗性能。第一次加载时,只加载一屏数据,表格下划,滚动条滚动到表格底部加载下一屏数据(距离可控)

  1. 利用element infinite-scroll,封装指令
 directives: {
    "load-more": {
      bind(el, binding, vnode) {
        const { expand } = binding.modifiers;
        let disabled = el.getAttribute("load-more-disabled");
        disabled = vnode[disabled] || disabled;
        if (disabled) return;  //如果是disabled,直接return
        // 使用更丰富的功能,支持父组件的指令作用在指定的子组件上
        if (expand) {
          /**
           * target 目标DOM节点的类名
           * distance 滚动加载距离底部触发得距离(单位px)
           * func 触发的方法
           * delay 防抖时延,单位为ms
           * load-more-disabled 是否禁用无限加载
           */
          let { target, distance = 1, func, delay = 200 } = binding.value;
          if (typeof target !== "string") return;
          let targetEl = el.querySelector(target);
          if (!targetEl) {
            console.log("Container Not Found");
            return;
          }
          binding.handler = debounce(function () {
            const { scrollTop, scrollHeight, clientHeight } = targetEl;
            if (scrollHeight <= scrollTop + clientHeight + distance) {
              func && func();
            }
          }, delay);
          targetEl.addEventListener("scroll", binding.handler);
        } else {
          binding.handler = debounce(function () {
            const { scrollTop, scrollHeight, clientHeight } = el;
            if (scrollHeight === scrollTop + clientHeight) {
              binding.value && binding.value();
            }
          }, 200);
          el.addEventListener("scroll", binding.handler);
        }
      },

      unbind(el, binding) {
        let { arg } = binding;
        // 使用更丰富的功能,支持父组件的指令作用在指定的子组件上
        if (arg === "expand") {
          const { target } = binding.value;
          if (typeof target !== "string") return;
          let targetEl = el.querySelector(target);
          targetEl && targetEl.removeEventListener("scroll", binding.handler);
          targetEl = null;
        } else {
          el.removeEventListener("scroll", binding.handler);
          el = null;
        }
      },
    },
  },

  1. 防抖函数,只记录最后一次触发得滚动
const debounce = function (func, delay) {
  let timer = null;
  return function () {
    if (timer) clearTimeout(timer);
    timer = null;
    let self = this;
    let args = arguments;
    timer = setTimeout(() => {
      func.apply(self, args);
    }, delay);
  };
};
  1. table中添加指令
 v-load-more.expand="{
        func: loadmore,
        distance: 400,
        target: '.el-table__body-wrapper',
        delay: 300,
      }"
      :load-more-disabled="loadDisabled"

5.绑定loadmore函数,可根据数据总数量>加载页*每页加载数量,判断是否需要继续加载数据

async loadmore() {},