elementUI的select下拉框如何下拉加载数据?

前言

相信大家都遇到过一个问题,select下拉选项数据特别多,要设置为分页,那么前端如何弄成下拉加载数据呢?来看看我是怎么弄的吧。

先来看看效果

template代码

javascript 复制代码
<el-select
  v-model="formDataModel[item.key]"
  :placeholder="'请选择' + item.label"
  filterable
  remote
  clearable
  :remote-method="remoteMethod"
  @clear="handleClear"
  @blur="handleBlur"
>
  <div
    class="options"
    v-infinite-scroll="load"
    :infinite-scroll-disabled="disabled"
    v-loading="isLoading"
  >
    <el-option
      v-for="(item, index) in options"
      :key="index"
      :label="item.name"
      :value="`${item.name}-${item.id}`"
    ></el-option>
    <p
      class="load-text"
      v-if="loading"
    >
      加载中...
    </p>
    <p
      class="load-text"
      v-if="noMore"
    >
      没有更多了
    </p>
  </div>
</el-select>

js代码

javascript 复制代码
// 弹框组件是否显示
@Prop({ type: Boolean, default: false }) isShow!: boolean;

@Watch('isShow', { immediate: true })
handleShowChange(val: boolean) {
  if (val) {
    this.keyword = '';
    this.pageIndex = 1;
    this.getOptions();
  }
}

// 清空选项
public handleClear() {
  this.remoteMethod('');
}

// 处理失去焦点
public handleBlur() {
  setTimeout(() => {
    if (!this.formDataRef.formDataModel.VBIFieldName) {
      this.remoteMethod('');
    }
  }, 500);
}

//#region 下拉加载开始
  public pageIndex = 1;
  public options: any[] = [];
  public loading = false;
  // 总数
  public total = 0;
  get noMore() {
    return this.options.length >= this.total;
  }
  get disabled() {
    return this.loading || this.noMore;
  }
  public async load() {
    this.pageIndex += 1;
    this.getVBIFieldNameOptions();
  }
  //#endregion 下拉加载结束

  public keyword = '';
  public isLoading = false;
  //获取选项
  public async getOptions() {
    if (this.pageIndex === 1) {
      // 搜索loading
      this.isLoading = true;
    } else {
      // 下拉加载loading
      this.loading = true;
    }
    try {
      let fetchApi: any;
      let paramsData = {
        pageIndex: this.pageIndex,
        pageSize: 10,
        name: this.keyword
      };
      const {
        data: {
          data: { records, total }
        }
      } = await fetchApi(paramsData);
      let list = records ?? [];
      if (this.pageIndex === 1) {
        this.options = list;
      } else {
        this.options = [...this.options, ...list];
      }
      this.total = total;
    } finally {
      if (this.pageIndex === 1) {
        // 搜索loading
        this.isLoading = false;
      } else {
        // 下拉加载loading
        this.loading = false;
      }
    }
  }

  // 根据输入框的值远程查询
  public async remoteMethod(query: string) {
    this.pageIndex = 1;
    this.keyword = query;
    this.getVBIFieldNameOptions();
  }

css代码

css 复制代码
.options {
  .load-text {
    margin: 0;
    text-align: center;
    color: #999;
    font-size: 12px;
  }
}

结语

大家可以参考一下实现逻辑,代码可能不能直接使用。

关注我,不迷路。

不定时分享前端相关问题以及解决方案。

希望能帮助每个在开发类似功能的小伙伴。

相关推荐
往事随风灬5 分钟前
我被 Volta 的“智能”坑了一下午:pnpm 为何无视项目 Node 版本?
前端·vue.js
xiaofeichaichai9 分钟前
Tree Shaking
前端·javascript
lichenyang4539 分钟前
给 ArkTS 应用做一个内置的「Network 面板」:实时看清 SSE 每一帧和最后那张卡片
前端
倾颜12 分钟前
从手写 Runner 到 LangGraph:受控 Agent 接入 LangGraph
前端·后端·langchain
UXbot19 分钟前
AI网页开发工具能替代工具吗?5大平台对比
前端·人工智能·低代码·ui·原型模式·web app
wuhen_n21 分钟前
从零到一!前端搭建本地轻量化 RAG 问答系统
前端·langchain·ai编程
落日漫游38 分钟前
代码报错难排查?借助Gemini快速修复
前端
niconicoC38 分钟前
让 Three.js 场景更真实:我用高斯泼溅和 SparkJS 做了一个可交互的 3D Demo
前端·webgl
Darling噜啦啦42 分钟前
JavaScript 数组深度解析:从纯函数到二维数组陷阱,一文吃透前端数据结构核心
前端·javascript·数据结构
万少42 分钟前
一封邮件,让我重新打开了搁置半年的鸿蒙应用
前端·javascript·后端