vue3 elementUI select 下拉加载更多(最新-组件封装)

  • directive.ts

  • import { Directive, DirectiveBinding } from 'vue'
    
    const loadMore: Directive = {
    	beforeMount(el: any, binding: DirectiveBinding) {
    		let arg = binding.arg as any
    		if (!arg) return
    		const selectDom = document.querySelector(`.${arg.name} .el-select-dropdown .el-select-dropdown__wrap`)
    		function loadMores(this: any) {
    			const isBase = this.scrollHeight - this.scrollTop <= this.clientHeight
    			if (isBase) {
    				binding.value && binding.value(arg)
    			}
    		}
    		el.selectDomInfo = selectDom
    		el.userLoadMore = loadMores
    		selectDom?.addEventListener('scroll', loadMores)
    	},
    	beforeUnmount(el: any) {
    		if (el.userLoadMore) {
    			el.selectDomInfo.removeEventListener('scroll', el.userLoadMore)
    			delete el.selectDomInfo
    			delete el.userLoadMore
    		}
    	}
    }
    export default loadMore
  • main.ts

  • import { createApp } from 'vue'
    import App from './App.vue'
    import router from '/@/router'
    import loadMore from './directive'
     
    const app = createApp(App)
    app.use(router).directive('loadMore', loadMore)
  • 封装后组件:scrollSelect文件下Index.vue

  • <script setup lang="ts">
    interface selectProps {
      modelValue: any; //选择赋值
      name: string; //一个父与子里面的下拉:不可重复
      methods: (data: any) => any; //接口方法
      label: any; //下拉中显示值
      multiple: boolean; //是否多选
      placeholder: string; //占位显示
      key: string; //Key源
      value: string; //value源
      disabled: boolean; //是否禁用
      change: Function | undefined; //下拉方法
    }
    const props = withDefaults(defineProps<selectProps>(), {
      modelValue: null,
      name: "select",
      label: null,
      multiple: false, //默认不可多选
      placeholder: "请选择",
      key: "ID", //默认
      value: "ID", //默认
      disabled: false, //默认不禁用
      change: () => {},
    });
    const emit = defineEmits(["update:modelValue"]);
    const modelCpd = computed({
      get() {
        return props.modelValue;
      },
      set(value) {
        emit("update:modelValue", value);
      },
    });
    
    const reSelect = reactive({
      modelValue: props.modelValue,
      name: props.name,
      PageIndex: 0,
      PageSize: 10,
      finished: false,
      optionList: [] as any,
      methods: props.methods,
    });
    
    //加载数据
    const loadMore = (Select: any) => {
      // 防抖处理
      setTimeout(async () => {
        if (Select.finished) return;
        Select.PageIndex += 1;
        var seacth = {
          name: Select.name,
          PageIndex: Select.PageIndex,
          PageSize: Select.PageSize,
        };
        console.log(seacth);
        let res = await Select.methods(seacth);
        if (res.Data && res.Data.length > 0) {
          Select.optionList = Select.optionList.concat(res.Data);
        }
        if (res.Total <= Select.optionList.length) {
          Select.finished = true;
        }
      }, 200);
    };
    
    //下拉显示值
    const getLabel = (obj: any, fields: string) => {
      let matchs = fields.match(/\w+/g);
      if (matchs == null) {
        return "";
      }
      matchs.forEach((element) => {
        fields = fields.replace(element, obj[element]);
      });
      return fields;
    };
    //默认加载
    loadMore(reSelect);
    </script>
    
    <template>
      <el-select
        v-model="modelCpd"
        v-loadMore:[reSelect]="loadMore"
        :popper-class="reSelect.name"
        :multiple="props.multiple"
        clearable
        collapse-tags
        collapse-tags-tooltip
        :placeholder="props.placeholder"
        filterable
        :disabled="props.disabled"
        @change="(value:any) => {
    			if(props.change != null)
    			{
    				props.change(value)
    			}
    		}"
      >
        <el-option
          v-for="item in reSelect.optionList"
          :key="item[props.key]"
          :value="item[props.value]"
          :label="getLabel(item, props.label ? props.label : 'Name')"
        />
      </el-select>
    </template>
    
  • 页面调用

  • <template>
        <scrollSelect
                  v-model="state.EquipmentList"
                  :name="'Equipment'"
                  :methods="接口方法"
                  :label="'EquipmentName-EquipmentCode'"
                  :multiple="true"
        />
    </template>
    
    <script setup lang="ts">
    import scrollSelect from "/@/components/scrollSelect/Index.vue";
    </script>
  • 效果

  • 23
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值