elementUI select 分页搜索组件

2021-11-24  本文已影响0人  一个小前端程序员

基于element-ui select封装,分页加载select数据,并且可以进行搜索,避免页面卡顿

组件代码

<template>
  <el-select
    v-model="selectValue"
    filterable
    :filter-method="onFilter"
    placeholder="请选择"
    v-el-select-load-more:rangeNumber="loadMoreFun(rangeNumber)"
    @change="onChange"
  >
    <el-option
      v-for="item in pageList.slice(0, rangeNumber)"
      :key="item[selectProps.value]"
      :label="item[selectProps.label]"
      :value="item[selectProps.value]"
    >
    </el-option>
  </el-select>
</template>

<script>
export default {
  props: {
    dic: {
      type: Array,
      default: () => [],
    },
    selectProps: {
      // select的key和value对应的字段
      type: Object,
      default: () => {
        return { label: "label", value: "value" };
      },
    },
    value: {
      type: Object,
      default: () => {},
    },
  },
  data() {
    return {
      selectValue: "",
      pageList: [],
      rangeNumber: 10, //下拉框滚动到底部后新增的条数
      defaultNumber: 10, //初始展示条数,每次加载条数
    };
  },
  created() {
    //   默认展示的
    this.pageList = this.dic;
    this.selectValue = this.value[this.selectProps.value];
  },
  watch: {
    dic() {
      this.pageList = this.dic;
    },
    value() {
      this.selectValue = this.value[this.selectProps.value];
    },
  },
  methods: {
    onFilter(val) {
      // 下拉框搜索
      this.rangeNumber = this.defaultNumber;
      this.pageList = this.dic.filter((item) => {
        const str = item[this.selectProps.label];
        const reg = RegExp(val);
        return reg.test(str);
      });
    },
    loadMoreFun(n) {
      //每次滚动到底部可以新增条数
      return () => (this.rangeNumber += this.defaultNumber);
    },
    onChange(value) {
      // 下拉框选中
      this.dic.some((item) => {
        if (item[this.selectProps.value] === value) {
          this.$emit("input", item);
          return true;
        }
      });
    },
  },
  //注册一个自定义指令 `v-el-select-load-more`
  directives: {
    "el-select-load-more": {
      bind(el, binding) {
        // 获取element-ui定义好的scroll盒子
        const SELECTWRAP_DOM = el.querySelector(
          ".el-select-dropdown .el-select-dropdown__wrap"
        );
        SELECTWRAP_DOM.addEventListener("scroll", function () {
          /**
           * scrollHeight 获取元素内容高度(只读)
           * scrollTop 获取或者设置元素的偏移值,常用于计算滚动条的位置, 当一个元素的容器没有产生垂直方向的滚动条, 那它的scrollTop的值默认为0.
           * clientHeight 读取元素的可见高度(只读)
           * 如果元素滚动到底, 下面等式返回true, 没有则返回false:
           * ele.scrollHeight - ele.scrollTop === ele.clientHeight;
           */
          const condition =
            this.scrollHeight - this.scrollTop <= this.clientHeight;
          if (condition) binding.value();
        });
      },
    },
  },
};
</script>

使用示例

html:
<pager-select
    :dic="projects"
    :selectProps="selectProps"
    v-model="projectInfo"
></pager-select>
js:
data() {
    return {
      selectProps: { label: "projectName", value: "id" },
      projects: [
          {projectName:"测试测试",id:"12313123"}
      ],
      projectInfo: {},
    };
  },
上一篇下一篇

猜你喜欢

热点阅读