<template>
  <el-select
    v-model="values"
    :clearable="clearable"
    :filterable="filterable"
    :multiple="multiple"
    :disabled="disabled"
    :value-key="valueKey"
    :collapse-tags="collapseTags"
    :multiple-limit="multipleLimit"
    :size="size"
    :name="name"
    :autocomplete="autocomplete"
    :placeholder="placeholder"
    ref="select"
    :popper-append-to-body="popperAppendToBody"
    :remote="remote"
    :remote-method="getListMethod"
    :no-match-text="noMatchText"
    :no-data-text="noDataText"
    :popper-class="popperClass"
    :reserve-keyword="reserveKeyword"
    :default-first-option="defaultFirstOption"
    :automatic-dropdown="automaticDropdown"
    @change="change"
    @focus="focusHandle"
    @visible-change="handle('visible-change', $event)"
    @remove-tag="handle('remove-tag', $event)"
    @clear="handle('clear', $event)"
    @blur="handle('blur', $event)"
    v-if="flag"
  >
    <p
      class="el-select-dropdown__empty"
      v-if="length === 0 && total === 0 && !loading"
    >
      无数据
    </p>
    <slot></slot>
    <slot name="prefix"></slot>
    <slot name="empty"></slot>
    <el-option
      v-for="item in list"
      :key="item[valueName]"
      :label="item[labelName]"
      :value="item[valueName]"
    ></el-option>
    <el-option
      v-if="defaultLabel"
      v-show="false"
      :label="defaultLabel"
      :value="defaultValue"
    ></el-option>
    <el-option v-show="false" label="" value="" v-if="loading"></el-option>
    <div
      style="
        display: flex;
        align-items: center;
        justify-content: center;
        height: 30px;
      "
      v-show="loading"
    >
      <i class="el-icon-loading"></i
      ><span
        style="
          font-size: 14px;
          color: #8492a6;
          display: inline-block;
          padding-left: 3px;
        "
        >加载中...</span
      >
    </div>
  </el-select>
</template>

<script>
export default {
  name: "select-scroll",
  model: {
    prop: "value", // 默认是value
    event: "value", // 默认是value
  },
  props: {
    list: Array,
    labelName:{
      type:String,
      default:'label'
    },
    valueName:{
      type:String,
      default:'value'
    },
    defaultLabel: String,
    defaultValue: [String, Number],
    disabledScroll: Boolean, // 禁止滚动加载
    disabled: Boolean, // 禁止滚动加载
    value: [String, Number, Array],
    total: Number,
    length: Number,
    pageCur: Number,
    pageSize: Number,
    loading: Boolean,
    multiple: Boolean,
    valueKey: String,
    size: String,
    collapseTags: Boolean,
    multipleLimit: Number,
    name: String,
    autocomplete: String,
    noMatchText: String,
    noDataText: String,
    popperClass: String,
    reserveKeyword: Boolean,
    defaultFirstOption: Boolean,
    automaticDropdown: Boolean,
    popperAppendToBody: Boolean,
    placeholder: {
      type: String,
      default() {
        return "请选择";
      },
    },
    clearable: {
      type: Boolean,
      default() {
        return true;
      },
    },
    filterable: {
      type: Boolean,
      default() {
        return true;
      },
    },
    remote: {
      type: Boolean,
      default() {
        return true;
      },
    },
  },
  watch: {
    value(val){
      this.values=val||""
    }
  },
  data() {
    return {
      values: "",
      flag:true
    };
  },
  mounted() {
    this.$nextTick(() => {
      this.values = this.value;
      this.init();
    });
  },
  beforeDestroy() {
    this.removeInt();
  },
  methods: {
    getList(flag, data) {
      const nextSize = this.pageCur * this.pageSize;
      if (this.loading || (!flag && nextSize > this.total)) return;
      this.$emit("handle", {
        type: flag ? "search" : "getList",
        data: data || "",
      });
    },
    change() {
      this.$emit("value", this.values);
      this.$emit("handle", {
        type: "change",
        data: this.values,
      });
    },
    focusHandle(event) {
      if (this.length === 0) {
        this.getListMethod();
      }
      this.handle("focus", event);
    },
    resetFlag(){
      this.flagTime && clearTimeout(this.flagTime)
      this.flagTime=setTimeout(()=>{
        this.flag=false
        this.$nextTick(()=>{
          this.flag=true
        })
      },500)
    },
    handle(type, event) {
      this.$emit("handle", {
        type: type,
        data: event,
      });
      if(type==='visible-change' && !event){
        this.resetFlag()
      }
    },
    getListHandle(event) {
      const scrollTriggerSize = 60;
      const maxScrollTop =
        event.target.scrollHeight - event.target.clientHeight;
      if (!this.length || this.length >= this.total) return;
      if (scrollTriggerSize + event.target.scrollTop > maxScrollTop) {
        this.userNameTimer && clearTimeout(this.userNameTimer);
        this.userNameTimer = setTimeout(() => {
          if (this.loading) return;
          this.getList();
        }, 200);
      }
    },
    getListMethod(query) {
      this.getList(true, typeof query === "string" ? query.trim() : "");
    },
    removeInt() {
      if (
        this.$refs.select &&
        this.$refs.select.$el &&
        this.$refs.select.$el.querySelector &&
        this.$refs.select.$el.querySelector(".el-scrollbar__wrap")
      ) {
        this.$refs.select.$el
          .querySelector(".el-scrollbar__wrap")
          .removeEventListener("scroll", this.getListHandle);
      }
    },
    init() {
      if (this.disabledScroll || this.disabled) return;
      if (
        this.$refs.select &&
        this.$refs.select.$el &&
        this.$refs.select.$el.querySelector &&
        this.$refs.select.$el.querySelector(".el-scrollbar__wrap")
      ) {
        this.$refs.select.$el
          .querySelector(".el-scrollbar__wrap")
          .addEventListener("scroll", this.getListHandle);
      }
    },
  },
};
</script>
