element 二次封装滚动下拉加载

1、首先创建文件loadmore-select.vue

<template>
 <el-select v-model="seVal"
              :value-key="beforOptions.k"
              filterable
              remote
              :remote-method="remoteFilter"
              :placeholder="beforOptions.placeholderVal"
              :clearable="beforOptions.clearable"
              v-load-more="loadMore"
              :default-first-option="true"
              @change="onChange($event)"
              @visible-change="visibleChange"
              :disabled="beforOptions.disabled"
              @remove-tag="removeTag"
              >
      <el-option v-for="(item,i) in loadData"
              :key="beforOptions.k+item[beforOptions.k]+i"
              :label="item[beforOptions.l]"
              :value="beforOptions.bindingObj ? item :item[beforOptions.k]"
              >
              <span v-if="beforOptions.isDel" style="float: left">{{ item[beforOptions.l] }}</span>
              <span v-if="beforOptions.isDel" style="float: right; color: #8492a6; font-size: 13px" @click.stop="deletePayees(item)">X</span>
      </el-option>
      <div class="load-more">
        <label v-if="finished">到底啦</label>
      <label v-else >滚动加载更多</label>
      </div>
    </el-select>
</template>

<script>
import service from '../searver';
const debounce = require('lodash.debounce');
export default {
  props: {
    echoData: [String],
    // 额外参数
    params: [Object],
    // 手动配置项
    options: [Object],
    value: [String, Number, Object] // 默认值

  },
  // 这里使用computed 拦截v-model
  computed: {
    seVal: {
      get(){
        return this.value;
      },
      set(v) {
        return this.$emit('input', v);
      }
    }
  },
  data () {
    return {
      // 默认配置项
      beforOptions: {
        isDel: false, // 是否删除项
        k: 'id', // key值
        l: 'name', // label值
        bindingObj: false, // value绑定的值
        placeholderVal: '请选择', // 提示文字
        clearable: true, // 是否可清空
        disabled: false, // 是否禁用
        pageNum: 1,
        pageSize: 10,
        url: '' // 请求地址
      },
      loadData: [],
      finished: false,
      filterArray: []  // 所有可展示的数据 (符合搜索条件 && newData没有的数据)
    };
  },
  created () {
    // 初始化配置项
    this.beforOptions = Object.assign(this.beforOptions, this.options);
  },
  mounted(){
    if(this.echoData) {
      this.remoteFilter(this.echoData);
    }else{
      this.loadMore();
    }
  },

  methods: {
    loadMore(){
      // 禁止重复请求
      if(this.finished){
        return;
      }
      let data = {
        pageNum: this.beforOptions.pageNum++,
        pageSize: this.beforOptions.pageSize,
        ...this.params
      };
      service.getTableList(this.beforOptions.url, data).then(({code, data}) => {
        if(code === 0){
          if(data && data.records && data.records.length > 0){
            this.loadData.push(...data.records);
          }
          // 判断是否到底
          this.finished = !data || (data.current ===  data.pages);
        }
      });

	 },
    visibleChange(v){
      if(v && this.seVal){
        this.remoteFilter('');
      }
    },
    remoteFilter: debounce(function (v) {
      // 当加载完毕时 直接退出方法
      this.beforOptions.pageNum=1;
      this.loadData = [];
      this.finished = false;
      this.params[this.beforOptions.l] = v;
      this.loadMore();
    }, 500,
    {
      leading: true,
      trailing: false
    }),
    onChange(data){
      this.$emit('onChange', data);
    },
    // 多选模式下 移除tag 触发
    removeTag(data){
      this.$emit('removeTag', data);
    },
    clearVal(){
      this.seVal = '';
    },
    // 下拉框删除事件
    deletePayees(data){
      this.$emit('deletePayees', data);
    }
  },
  // 组件销毁   重新加载
  destroyed(){
    this.loadData = [];
  }
};
</script>

<style lang="scss" scoped>
div label {
    font-size: 12px;
    text-overflow: ellipsis;
    color: #969696;
    height: 34px;
    line-height: 34px;
    box-sizing: border-box;
}
.load-more{
  width: 100%;
  height: 34px;
  line-height: 34px;
  text-align: center;
  color: #969696;
}
</style>

这里使用的是v-load-more指令,如图

export default {
  bind(el, binding) {
    const root = el.querySelector('.el-select-dropdown .el-select-dropdown__wrap');
    const dropdownDom = el.querySelector('.load-more');
    // 创建一个IntersectionObserver实例
    const observer = new IntersectionObserver((entries) => {
      // 检查是否有元素进入视口
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          // 调用绑定的方法
          binding.value();

        }
      });
    }, {
      root, // 相对于元素本身进行观察
      rootMargin: '0px',
      threshold: 1.0 // 当元素100%进入视口时触发
    });
    observer.observe(dropdownDom);
  }
};

接下来就是使用方法

 <loadmmoreSelect
              class="ipt"
              v-model="viewMb.task[index].assignee"
              :echoData="viewMb.task[index].assigneeName"
              :options="{
                k:'roleId',
                l:'roleName',
                placeholderVal:'请选择审批角色',
                url:'system/page'
              }"
              :params="{
                districtId:currentUser.districtInfo.districtId,
                roleKey: 'approve'
              }"
    />

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值