element-ui——select多选框远端搜索组件封装

车胤运
2023-12-01

1. 效果

  • 在select框中输入内容
  • 输入内容后发起远端网络请求,返回options列表
  • 选择内容,在select框中展示
  • 获取值并处理成对应格式,操作时发给后端

2. select封装组件代码片段

  • html:
<template>
  <div class="skuList">
    <el-select
      ref="skuDom"
      v-model="skuValue" // 输入框中对应绑定选择的值
      :multiple="multiple" // 支持多选
      filterable // 可以输入内容进行过滤
      remote	// 支持远端搜索
      reserve-keyword // 在选中选项后保留当前的搜索关键词
      :multiple-limit="multipleLimit" // 最大多选项目数
      :placeholder="placeholder"
      :remote-method="remoteMethod"  // 发起网络请求的方法
      :loading="loading"
      :size="size"
      style="width: 100%"
      @change="selectSku" // 多选框内数据发生变化,执行对应方法,双向绑定
    >
      <el-option
        v-for="item in options"
        :key="item.code"
        :label="item.value"
        :value="item.code + ',' + item.value">
      </el-option>
    </el-select>
  </div>
</template>
<script lang="ts" src="./index.ts"></script>
  • ts
import { Component, Prop, Vue, Watch } from 'vue-property-decorator'
import api from './api'

@Component({
  name: 'sku_list'
})

export default class extends Vue {
  @Prop() private multipleLimit: number
  @Prop({ default: 'mini' }) private size: string
  @Prop({ default: '请输入sku关键字后选择' }) private placeholder: string
  @Prop({ default: '' }) private value: string[]
  private loading = false
  private options = []
  private skuValue: string[] = []
  private multiple = true // 仅支持多条,若单条,则可以选择multiple-limit 1

  @Watch('value', { deep: true, immediate: true })  // 在编辑时 组件接收的值发生变化,及时响应
  onValueChange(val: string[]) {
    this.skuValue = val
    if (!val || !val.length) return // 如果是清空操作的话,就直接赋值
    val = val.filter((f) => { 
      return f
    })
    this.skuValue = val
    const ids: string[] = []
    const names: string[] = []
    val.forEach((f: string) => { // 进行回显操作的处理,把选中值的code和name分别提取出来,用于回显
      const splitStr = f && f.split(',')
      ids.push(splitStr[0])
      names.push(splitStr[1])
    })
    for (let i = 0; i < val.length; i++) {
      this.options.push({ // 之前选中的值,回显到select中,并将选择的值填入列表中
        // @ts-ignore
        code: ids[i],
        // @ts-ignore
        value: names[i]
      })
      this.options = this.unique(this.options)  // options去重,避免新请求到的列表与回显列表有重合报错
    }
  }

  // 数组去重
  unique<T>(arr: T[]): T[] {
    let obj: Record<string, string> = {}
    arr = arr.reduce((cur: any, next: any) => {
      if (obj[next.value]) {
        obj[next.value] = ''
      } else {
        obj[next.value] = 'true'
        cur.push(next)
      }
      return cur
    }, [])
    return arr
  }

  // 远程获取sku列表数据
  async remoteMethod(searchStr: string) {
    if (searchStr) {
      this.loading = true
      try {
        const res = await api.getSkuList(searchStr)
        if (res.success && res.status === 0) {
          this.options = res.data
          return res.data || []
        }
      } catch (e) {
        return []
      } finally {
        this.loading = false
      }
    }
  }

  // 多选框内数据变化
  selectSku(item: string | string[]) {
    if (typeof item === 'string') {
      item = [item]
    }
    this.$emit('input', item) // 双向绑定
    this.$emit('change', item)
  }
}

3. 外部引入select组件

import SkuList from '@/components/SkuList/index.vue'

<SkuList v-model="old_sku_id"/>

如果有用,点个赞呗~

总结用法,希望可以帮助到你,
我是Ably,你无须超越谁,只要超越昨天的自己就好~

 类似资料: