目 录CONTENT

文章目录

基于antdv有可键入搜索的选择器

萧瑟
2023-03-27 / 0 评论 / 4 点赞 / 387 阅读 / 4,253 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2023-03-27,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

显示效果

inputSearch

传参效果

image-1679888862778

使用说明

    本组件基于ant design Vue 和 Vue开发(JeecgBoot Vue2.0),带有搜索和键入

组件功能

  1. 支持动态传入请求路径
  2. 动态设置请求方法
  3. 动态设置是否模糊查询
  4. 动态将请求方法进行带过来
  5. 支持键入搜索,根据输入内容后端将数据全部返回,前端可以设置显示条数,未显示内容通过键入具体细节进行展示,支持数据回显

组件详情

<!--
    全局键入搜索组件

    解决编辑回显是id:
    allowClear:向外暴露清除文本框事件
    inputChange: 向外暴露选中对象的事件
 -->
<template>
  <div>
    <a-select
      show-search
      allowClear
      :value="inValue"
      :style="{ width: width && width instanceof Number ? width + 'px' : width }"
      :placeholder="placeholder"
      :default-active-first-option="defaultActiveFirstOption"
      :show-arrow="showArrow"
      :filter-option="filterOption"
      :not-found-content="notFundContent"
      @search="handleSearch"
      @change="handleChange"
      @focus="handleFocus"
      @dropdownVisibleChange="handleDropDown"
      :disabled="disabled"
    >
      <a-icon slot="clearIcon" type="close-circle" @click="allowClear" />
      <a-select-option v-for="item in resData" :key="item[routeKey]">
        {{
          field
            .map((j) => {
              return item[j]
            })
            .toString()
        }}
      </a-select-option>
    </a-select>
  </div>
</template>

<script>
// 接口封装
import { getAction, postAction } from '@api/manage'

export default {
  props: {
    //指定循环的key(列表中不可重复的参数)
    routeKey: {
      type: String,
      default: 'id',
    },
    // 给后端传的请求参数
    params: {
      type: Array,
      required: false,
      default: ['route']
    },
    //指定要放的字段
    field: {
      type: Array,
      default: []
    },
    // 防止编辑的时候回显成id
    inValue: {
      type: String
    },
    // 宽度
    width: {
      type: [Number, String],
      default: 500
    },
    // 请求方式
    methodFn: {
      type: String,
      default: 'get'
    },
    // 请求路径
    inputUrl: {
      type: String,
      required: true
    },
    // 输入的值
    value: {
      type: undefined
    },
    // 提示内容
    placeholder: {
      type: String,
      default: '请选择内容'
    },
    // 是否默认高亮第一个选项。
    defaultActiveFirstOption: {
      type: Boolean,
      default: true
    },
    // 是否显示下拉小箭头
    showArrow: {
      type: Boolean,
      default: true
    },
    // 当下拉列表为空时显示的内容
    notFundContent: {
      type: null,
      default: null
    },
    // 是否需要模糊搜索(业务自定义)
    ifNeedAsterisk: {
      type: Boolean,
      default: false
    },
    // 父组件带过来 需要在列表接口传的参数
    customParams: {
      type: Object,
      default(){
        return {}
      }
    },
    // 是否禁用
    disabled: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      resData: [],    // 通过接口获取到的列表数据
    }
  },
  methods: {
    // 清除事件
    allowClear() {
      this.$emit('input', '')
      this.$emit('allowClear')
    },
    
    // 文本框值变化时回调
    handleSearch(value) {
      if (value.trim() == '') {
        this.resData = []
        return
      }
      if (this.methodFn.toUpperCase() == 'GET') {
        this.requestFn(value)
      } else if (this.methodFn.toUpperCase() == 'POST') {
      }
    },
    
    // 选中 option,或 input 的 value 变化(combobox 模式下)时,调用此函数
    handleChange(value) {
      let result = this.resData.filter((item) => {
        if (item[this.routeKey] === value) {
          return item
        }
      })
      this.$emit('input', value)
      //   将选中的对象交给父组件
      this.$emit('inputChange', result)
    },
    
    // 获得焦点时回调
    handleFocus() {
      this.requestFn('')
    },
    
    // 请求方法
    async requestFn(value) {
      try {
        let params = {
          [this.params[0]]: this.ifNeedAsterisk ? `*${value.trim()}*` : value.trim(),
          pageSize: 10000
        }
        
        params = {
          ...params,
          ...this.customParams
        }
        const res = await getAction(this.inputUrl, params)
        if (res.code === 200) {
          // 数据多的话只显示一部分
          const data = Array.isArray(res.result) ? [...res.result] : (res.result && res.result.records && Array.isArray(res.result.records)) ? [...res.result.records] : []
          if (data.length > 20) {
            this.resData = data.slice(0, 20)
          } else {
            this.resData = [...data]
          }
        } else {
          this.$message.info(res.message)
        }
      } catch (error) {
        console.error(error)
      }
    },
    
    // 展开下拉菜单的回调
    handleDropDown() {
    },
    
    // 是否根据输入项进行筛选。当其为一个函数时,会接收 inputValue option 两个参数,当 option 符合筛选条件时,应返回 true,反之则返回 false。
    filterOption(input, option) {
      return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
    }
  }
}
</script>

<style>
</style>

调用详情

v-model: 前端进行双向数据绑定的值

inValue: 防止编辑的时候回显成id

methodFn:请求方式

routeKey:指定循环的key(必须唯一,默认:id)

params:请求参数

field:指定要放的字段

inputUrl:请求路径

placeholder:选择框默认文字

ifNeedAsterisk:是否需要模糊查询(业务中定为:true加*为模糊查询,false不加为精确查询)

allowClear:是否支持清空

inputChange:选中 option,或 input 的 value 变化(combobox 模式下)时,调用此函数

<InputSearch
    v-model="xxx"
    :inValue="inValue"
    methodFn="get"
    :routeKey="routeKey"
    :params="['name']"
     :field="['name']"
    :inputUrl="url.nameUrl"
    placeholder="请选择名字"
    :ifNeedAsterisk="true"
    @allowClear="handleFactoryClear"
    @inputChange="handleFactoryChange"
></InputSearch>
data(){
    xxx:'',
    factoryValue: undefined,
    routeKey: 'id',
    inValue: undefined,
    url:{
        nameUrl: ''
    }
}

4

评论区