el-select数据过多单独封装防抖节流

下拉数据几千条,直接使用防抖节流操作,先封装一个el-select的组件,默认下拉展示10条数据,划到最后一条再多加载10条,一次内推

  1. 定义父子关系,获取所有数据后传入封装el-select组件

父组件:periodslistend:通过接口获取到所有下拉的数据,periodNum2:双向绑定的数据,可以设置默认值,periodslist为了区分俩个下拉选择器的开始和结束的数据,结束日期之前的数据在开始日期之前都是禁用状态。flag:判定开始还是结束

// 引用封装的下拉框组件
import loadselect from "../component/select";
 <loadselect
                :compareopt="periodslist"
                :compare="periodNum1"
                :resOptions="periodslist"
                :list="periodslistend"
                :flag="'s'"
                @parentHandler="choose_start1"
              ></loadselect>
 <!-- 封装一个防抖节流的element下拉框组件 -->
 //子组件接受父组件传值。
  <el-select
      v-model="compares"
      :placeholder="$t('language.general.select')"
//可搜索
      filterable
//自定义搜索方法
      :filter-method="filterMethod"
      @visible-change="visibleChange"
//自定义指令
      v-el-select-loadmore="loadMore(rangeNumber)"
//下拉选择改变事件
      @change="changefunc"
//失去焦点事件
      @focus="update"
    >
//把获取到的所有数据赋值给compareopt,rangeNumber限制10条
  <el-option
        v-for="item in compareopt.slice(0, rangeNumber)"
        :key="item.period_num"
        :label="item.period_num + ': ' + item.date + ' ' + item.time"
        :value="item.value"
        :disabled="flag=='s'?item.isdis:flag=='e'?item.disabled:false"
      ></el-option>
    </el-select>

//script
import { _debounce } from "../../../static/utils";
export default {
  name: "loadselect",
  //   接收子组件传来的值
  props: {
    compareopt: {
      type: Array,
      default: [],
    },
    compare: [String, Number],
    resOptions: {
      type: Array,
      default: [],
    },
    list: {
      type: Array,
      default: [],
    },
    flag: {
      type: String,
      default: "s",
    },
  },
  data() {
    return {
      // 测试下拉框内容过多卡顿的问题2021.1.8
      rangeNumber: 10,
    };
  },
  computed: {
    compares: {
      get() {
        var that = this;
        return that.compare;
      },
      set(val) {
        return val;
      },
    },
  },
  mounted() {
    console.log(this.compare);
  },
  watch: {
    compare(newval, oldval) {
      var that = this;
      that.compares=newval
      //   区分开始周期和结束周期
      //   开始周期
      if (that.flag == "s") {
        for (var i = 0; i < that.list.length; i++) {
          if (that.list[i].value < newval) {
            that.list[i].disabled = true;
          } else {
            that.list[i].disabled = false;
          }
        }
      } else if (that.flag == "e") {
        for (var i = 0; i < that.list.length; i++) {
          if (that.list[i].value > newval) {
            that.list[i].isdis = true;
          } else {
            that.list[i].isdis = false;
          }
        }
      }
    },
  },
  methods: {
    //  获取焦点就强制刷新一次数据,不然会有延迟
    update() {
      this.$forceUpdate();
    },
    // 2020.1.8测试下拉框内容过多卡顿的问题
    loadMore(n) {
      // n是默认初始展示的条数会在渲染的时候就可以获取,具体可以打log查看
      // elementui下拉超过7条才会出滚动条,如果初始不出滚动条无法触发loadMore方法
      return () => (this.rangeNumber += 5); // 每次滚动到底部可以新增条数  可自定义
    },
    // 筛选方法
    filterMethod: _debounce(function (filterVal) {
      console.log(filterVal,'筛选数组');
      if (filterVal) {
        //---20210916-add-zjl---
        //debugger;
        //---添加属性值label判断,无label时通过value过滤
        var is_label = false;
        var oneObj = (this.resOptions.length > 0) ? this.resOptions[0] : {};
        if (oneObj != {}) {
          for (var key in oneObj) {
            if (key == "label") {
              is_label = true;
              break
            }
          }
        }
        //---20210916-add-zjl---

        let filterArr = this.resOptions.filter((item) => {
          if(!is_label) return (item.value+"").toLowerCase().includes(filterVal.toLowerCase());
          return item.label.toLowerCase().includes(filterVal.toLowerCase());
        });
        this.compareopt = filterArr;
      } else {
        
        this.compareopt = this.resOptions;
        console.log(this.compareopt,'筛选数组元素赋值');
      }
    }, 500),
    // 下拉框出现时,调用过滤方法
    visibleChange(flag) {
      if (flag) {
        this.filterMethod();
      }
    },
    changefunc(val) {
      var that = this;
      that.$forceUpdate();
      this.$emit("parentHandler", val);
    },
  },
  // 自定义指令
  directives: {
    "el-select-loadmore": (el, binding) => {
      // 获取element-ui定义好的scroll盒子
      const SELECTWRAP_DOM = el.querySelector(
        ".el-select-dropdown .el-select-dropdown__wrap"
      );
      if (SELECTWRAP_DOM) {
        SELECTWRAP_DOM.addEventListener("scroll", function () {
          /**
           * scrollHeight 获取元素内容高度(只读)
           * scrollTop 获取或者设置元素的偏移值,
           *  常用于:计算滚动条的位置, 当一个元素的容器没有产生垂直方向的滚动条, 那它的scrollTop的值默认为0.
           * clientHeight 读取元素的可见高度(只读)
           * 如果元素滚动到底, 下面等式返回true, 没有则返回false:
           * ele.scrollHeight - ele.scrollTop === ele.clientHeight;
           */
          const condition =
            this.scrollHeight - Math.ceil(this.scrollTop) <= this.clientHeight;
          if (condition) binding.value();
        });
      }
    },
  },
};

节流功能实现

function _debounce(fn, delay = 300) {
    var timer = null;
    return function () {
      var _this = this;
      var args = arguments;
      if (timer) clearTimeout(timer); 
      timer = setTimeout(function () {
        fn.apply(_this, args);
      }, delay);
    };
  }
  export {
    _debounce
  }

文章到此结束,希望对你有所帮助

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值