Vue3 封装一个支持输入和单/多选InputSelect组件-Antd详解

 更新时间:2024年09月25日 12:08:36   作者:掉毛的小羊羔  
Antd的Select组件默认不支持作为输入框使用或手动添加选项,为了实现这一功能,我们封装了一个通用组件,支持单选和多选模式,并允许用户在组件失焦时手动输入选项,主要通过定义searchText存储输入数据,感兴趣的朋友跟随小编一起看看吧

写在前面:

Antd提供的select组件是不支持当作输入框使用的,并且不支持在一级状态下手动输入选项,所以就封装了一个和通用组件来实现上述功能。

组件效果:

单选模式:

多选模式:

实现步骤:

1.首先定义一个searchText存储用户输入的数据,因为会触发一个Antd定义的@Search事件,所以直接在onSearch数据收集即可

const searchText = ref('')
const onSearch = val => {
  // 去除首尾空格
  const text = val.trim()
  if (text) {
    searchText.value = text
  }
}

2.定义三个prop控制输入的数据,组件模式以及是否允许输入

const props = defineProps({
  value: {
    type: [Array, String, Number],
    default: undefined
  },
  mode: {
    type: String,
    default: ''
  },
  allowInputValue: {
    type: Boolean,
    default: true
  }
})

3.在组件失焦时完成数据传递,其实组件功能的核心就是在失焦时完成

首先,通过条件判断allowInputValue.value && searchText.value判断是否允许输入且存在搜索文本。 如果条件成立,继续执行下面的逻辑。

接着,通过判断tempMode.value === 'multiple'判断选择模式是否为多选。

如果选择模式为多选,则将搜索文本searchText.value添加到tempValue.value的数组中,即将搜索文本作为一个新的选项添加到选中值中。

如果选择模式不是多选,则直接将搜索文本赋值给tempValue.value,即将搜索文本作为选中值。

然后,通过emit('change', tempValue.value)触发change事件,并将当前的选中值作为参数传递给父组件。

最后,将searchText.value清空,以便下一次输入。

const emit = defineEmits(['update:value', 'update:mode', 'change'])
//组件失去焦点
const onBlur = () => {
  if (allowInputValue.value && searchText.value) {
    if (tempMode.value === 'multiple') {
      tempValue.value.push(searchText.value)
    } else {
      tempValue.value = searchText.value
    }
    emit('change', tempValue.value)
    searchText.value = ''
  }
}

4.定义$attrs以及slot支持进一步拓展及支持a-select原生api

<template>
  <a-select
    v-bind="$attrs"
    v-model:value="tempValue"
    :mode="tempMode"
    @search="onSearch"
    @blur="onBlur"
    @change="onChange"
  >
    <template v-for="(item, key, index) in $slots" :key="index" #[key]>
      <slot :name="key"></slot>
    </template>
  </a-select>
</template>

完整代码:

<template>
  <a-select
    v-bind="$attrs"
    v-model:value="tempValue"
    :mode="tempMode"
    @search="onSearch"
    @blur="onBlur"
    @change="onChange"
  >
    <template v-for="(item, key, index) in $slots" :key="index" #[key]>
      <slot :name="key"></slot>
    </template>
  </a-select>
</template>
<script setup>
import { computed, ref, toRefs } from 'vue'
const props = defineProps({
  value: {
    type: [Array, String, Number],
    default: undefined
  },
  mode: {
    type: String,
    default: ''
  },
  allowInputValue: {
    type: Boolean,
    default: true
  }
})
const emit = defineEmits(['update:value', 'update:mode', 'change'])
const { value, mode, allowInputValue } = toRefs(props)
const tempValue = computed({
  set: val => emit('update:value', val),
  get: () => value.value
})
const tempMode = computed({
  set: val => emit('update:mode', val),
  get: () => mode.value
})
const searchText = ref('')
const onSearch = val => {
  // 去除首尾
  const text = val.trim()
  if (text) {
    searchText.value = text
  }
}
const onBlur = () => {
  if (allowInputValue.value && searchText.value) {
    if (tempMode.value === 'multiple') {
      tempValue.value.push(searchText.value)
    } else {
      tempValue.value = searchText.value
    }
    emit('change', tempValue.value)
    searchText.value = ''
  }
}
const onChange = () => {
  emit('change', tempValue.value)
  searchText.value = ''
}
</script>
<style lang="scss" scoped></style>

使用范例:

单选:

  <InputSelect
      v-model:value="record.name"
      placeholder="请选择或输入"
      :options="headerOptions"
      allow-clear
      show-search
      max-tag-count="responsive"
     />

多选:

<InputSelect
  v-model:value="modelRef.actList"
  class="value-item"
  mode="multiple"
  placeholder="请选择或输入"
  :options="ACT_TYPES"
  allow-clear
  show-search
  max-tag-count="responsive"
  @change="onChange"
 />

到此这篇关于Vue3 封装一个支持输入和单/多选InputSelect组件-Antd详解的文章就介绍到这了,更多相关Vue3 InputSelect组件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 一个Vue视频媒体多段裁剪组件的实现示例

    一个Vue视频媒体多段裁剪组件的实现示例

    这篇文章主要介绍了一个Vue媒体多段裁剪组件的实现示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • 基于vue开发微信小程序mpvue-docs跳转页面功能

    基于vue开发微信小程序mpvue-docs跳转页面功能

    这篇文章主要介绍了基于vue写微信小程序mpvue-docs跳转页面,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-04-04
  • vue.config.js里面的devserver如何配置

    vue.config.js里面的devserver如何配置

    本文介绍了vue.config.js中devServer的常见配置方式,包括基本配置、代理配置、热模块替换、静态资源服务、HTTPS配置、多代理配置以及其他配置项,帮助开发者根据项目需求进行定制
    2025-01-01
  • 正确更改Ant Design of Vue样式的问题

    正确更改Ant Design of Vue样式的问题

    这篇文章主要介绍了正确更改Ant Design of Vue样式的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-09-09
  • Vue.js 时间转换代码及时间戳转时间字符串

    Vue.js 时间转换代码及时间戳转时间字符串

    这篇文章主要介绍了Vue.js 时间转换代码及时间戳转时间字符串,需要的朋友可以参考下
    2018-10-10
  • vue后台管理之动态加载路由的方法

    vue后台管理之动态加载路由的方法

    这篇文章主要介绍了vue后台管理之动态加载路由的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • 在Vue3中使用vue3-print-nb实现前端打印功能

    在Vue3中使用vue3-print-nb实现前端打印功能

    在前端开发中,经常需要打印页面的特定部分,比如客户列表或商品详情页,要快速实现这些功能,可以使用 vue3-print-nb 插件,本文就给大家介绍了如何在 Vue 3 中使用 vue3-print-nb 实现灵活的前端打印,需要的朋友可以参考下
    2024-06-06
  • vue实现城市列表选择功能

    vue实现城市列表选择功能

    这篇文章主要介绍了vue实现城市列表选择功能,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-07-07
  • Vue组件间通信方式全面汇总介绍

    Vue组件间通信方式全面汇总介绍

    这篇文章主要介绍了Vue组件间通信方式全面汇总,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2023-04-04
  • 使用vue-draggable-plus实现拖拽排序

    使用vue-draggable-plus实现拖拽排序

    最近遇到一个需求,在 Vue3 的一个 H5 页面当中点击拖拽图标上下拖动 tab 子项,然后点击保存可以保存最新的 tab 项顺序,同事说可以用 vue-draggable-plus 这个库来实现拖拽,所以本文给大家介绍了如何使用vue-draggable-plus实现拖拽排序,需要的朋友可以参考下
    2024-01-01

最新评论