【vue+Element】el-select远程搜索&动态加载

在我们使用 Element 的 el-select 时,当下拉框的选项过多,我们一次性将所有选项都放入下拉框中会导致页面卡顿,每次点击下拉框都会出现白屏,我们可以用自定义指令实现下拉框的动态加载。

首先,在main.js文件中我们可以定义一个全局的指令

Vue.directive('loadmore', {
  bind(el, binding) {
    const dom = el.querySelector('.el-select-dropdown .el-select-dropdown__wrap')
    dom.addEventListener('scroll', function () {
      const condition = this.scrollHeight - this.scrollTop <= this.clientHeight
      if (condition) {
        binding.value()
      }
    })
  }
});

将动态加载的 el-select 封装成一个公共组件以便复用,起名为 MySelect.vue

<template>
  <el-select
    size="small"
    multiple
    v-bind="$attrs"
    v-loadmore="loadProject"
    collapse-tags
    filterable
    :clearable="clearableFlag"
    :placeholder="placeholder"
    :filter-method="handleFilter"
    v-model="val"
    @change="handleSearch"
    @visible-change="handleVisibleProject"
  >
    <el-option
      v-for="item in data.list"
      :key="item.number"
      :value="item.number"
      :label="item.name"
    >
      {{ item.name }}
    </el-option>
  </el-select>
</template>
<script>
import _ from "lodash";
import { api } from "@/apis";
export default {
  model: {
    prop: "inputValue",
    event: "change",
  },
  props: {
    clearableFlag: {
      type: Boolean,
      default: false,
    },
    inputValue: {
      type: [Array, String],
      default: () => {
        return [];
      },
    },
    placeholder: {
      type: String,
      default: "请选择",
    },
    size: {
      type: String,
      default: "medium",
    }
  },
  watch: {
    inputValue(newValue, oldValue) {
      this.val = newValue;
    },
  },
  data() {
    return {
      val: "",
      data: {
        list: [],
        total: 0,
      },
      // 请求参数
      query: {
        name: "",
        currentPage: 1,
        pageSize: 20,
      },
      isFristLoad: true,
    };
  },
  methods: {
    // 分页加载数据项
    loadProject() {
      const { pageSize, currentPage } = this.query;
      if (pageSize * currentPage < this.data.total) {
        this.query.currentPage++;
        this.getList();
      }
    },
    // 通过调用接口获取数据项
    getList() {
      // 下面是举例写法
      // api.getList(this.query).then((res) => {
      //   if (res.data.success) {
      //     this.data.list = [...this.data.list, ...res.data.data.list];
      //     this.data.total = res.data.data.total;
      //   }
      // });
    },
    // 筛选数据项
    handleFilter: _.debounce(function (val) {
      this.query.name = val;
      this.query.currentPage = 1;
      this.data.list = [];
      this.data.total = 0;
      this.getList();
    }, 500),
    // 隐藏显示下拉框
    handleVisibleProject(tag) {
      const { name } = this.query;
      if (!tag) {
        if (name !== "") {
          this.handleFilter("");
        }
      } else if (this.isFristLoad) {
        this.isFristLoad = false;
        this.getList();
      }
    },
    handleSearch(val) {
      this.$emit("change", val);
    },
  },
};
</script>

在页面中引入我们刚刚封装的MySelect组件

<template>
  <MySelect
    placeholder="请输入"
    v-model="keyword"
    @change="handleSearch"
  />
<template>

import { MySelect } from "@/components/MySelect"
export default {
  components: {
    MySelect
  },
  data() {
    return {
      keyword: ""
    }
  },
  methods: {
    handleSearch() {}
  }
}

快在自己的项目中试一试吧~

  • 7
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值