element ui封装可搜索下拉框(解决数据过多卡顿问题)

该博客介绍了Vue自定义组件FilterSelect的实现,该组件用于创建一个可过滤、可清空、可搜索的下拉选择框。组件通过v-model双向绑定值,并监听输入变化,同时在数据更新时自动处理回显和数据限制。文章详细展示了组件的模板、脚本部分,包括属性、方法和数据处理,特别是搜索方法handleFilter,用于过滤选项并限制显示数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

FilterSelect.vue

<template>
  <el-select
    v-model="innerValue"
    :disabled="disabled"
    filterable
    clearable
    :placeholder="placeholder"
    :filter-method="handleFilter"
    @change="changeHandler"
  >
    <el-option
      v-for="item in options"
      :key="item[keyField]"
      :label="item[labelField]"
      :value="item[valueField]"
    />
  </el-select>
</template>
<script>
export default {
  name: 'FilterSelect',
  model: {
    // model选项可以自定义prop名称和event名称
    prop: 'value',
    event: 'handleSelectChange'
  },
  props: {
    // 下拉框数据
    value: {
      type: String,
      default: () => ''
    },
    selectList: {
      type: Array,
      default: () => []
    },
    disabled: {
      type: Boolean,
      default: () => false
    },
    placeholder: {
      type: String,
      default: () => '请选择'
    },
    labelField: {
      type: String,
      default: () => 'label'
    },
    valueField: {
      type: String,
      default: () => 'value'
    },
    keyField: {
      type: String,
      default: () => 'key'
    }
  },
  data() {
    return {
      //  下拉框实际渲染的数据
      options: [],
      innerValue: ''
    }
  },
  watch: {
    value(val) {
      // 将value同步到innerValue
      this.innerValue = val
    },

    options(val) {
      // 回显功能
      if (
        val.length > 0 &&
        this.selectList.length > 0 &&
        this.valueField &&
        this.value
      ) {
        const optionIsContain = val.filter(
          (item) => item[this.valueField] === this.value
        )
        if (optionIsContain.length === 0) {
          const activeItem = this.selectList.filter(
            (item) => item[this.valueField] === this.value
          )[0]
          this.options.unshift(activeItem)
        }
      }
      // 长度控制
      if (val.length > 30) {
        this.options = val.slice(0, 30)
      }
    },
    'selectList.length': function(n, o) {
      if (n !== o) {
        this._initData()
      }
    }
  },
  mounted() {
    this._initData()
  },
  methods: {
    // 初始化数据
    _initData() {
      this.options =
        this.selectList.length <= 30
          ? this.selectList
          : this.selectList.slice(0, 30)
      // 初始化选中值
      this.innerValue = this.value
    },
    // v-model关键函数
    changeHandler(val) {
      this.$emit('handleSelectChange', val)
    },
    // 搜索函数
    handleFilter(query) {
      if (query !== '') {
        this.options = this.selectList
          .filter((item) => {
            return (
              item[this.labelField].toLowerCase().indexOf(query.toLowerCase()) >
              -1
            )
          })
          .slice(0, 30)
      } else {
        this.options =
          this.selectList.length > 30
            ? this.selectList
            : this.selectList.slice(0, 30)
      }
    }
  }
}
</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端小端长

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值