AutoComplete 自动完成

本质是增强型 Input:监听输入给出建议列表,保留上次选中值,只允许字符串返回。

何时使用

  • 输入时根据用户输入实时提供补全建议时。
  • 选项较多、需要搜索过滤时。

基础用法

通过 onSearch 监听输入,更新 data 提供建议。

<script setup lang="ts">
import { ref } from "vue";
import { AutoComplete } from "@reglow/reui";

const value = ref("");
const data = ref<string[]>([]);

const onSearch = (val: string) => {
  data.value = val
    ? ["gmail.com", "163.com", "qq.com"].map((d) => `${val}@${d}`)
    : [];
};
</script>

<template>
  <AutoComplete
    v-model:value="value"
    :data="data"
    show-clear
    placeholder="请输入邮箱"
    @search="onSearch"
  />
</template>

导入

import { AutoComplete } from "@reglow/reui";

更多示例

对象数组数据

data 支持对象数组,每个对象需包含 valuelabel

<script setup lang="ts">
import { ref } from "vue";
import { AutoComplete } from "@reglow/reui";

const data = ref([
  { value: "semi", label: "Semi Design" },
  { value: "shadcn", label: "shadcn/ui" },
  { value: "ant", label: "Ant Design" },
]);
</script>

<template>
  <AutoComplete
    :data="data"
    placeholder="请选择设计系统"
    @select="(item) => console.log('选中', item)"
  />
</template>

自定义候选项渲染

通过默认 slot 自定义候选项渲染。

<script setup lang="ts">
import { ref } from "vue";

const data = ref([
  { value: "1", label: "张三", email: "zhangsan@example.com" },
  { value: "2", label: "李四", email: "lisi@example.com" },
]);
</script>

<template>
  <AutoComplete :data="data" placeholder="搜索用户">
    <template #default="{ item }">
      <div class="flex items-center gap-2">
        <div class="w-6 h-6 rounded-full bg-primary/20 flex items-center justify-center text-xs">
          {{ item.label[0] }}
        </div>
        <div>
          <div class="text-sm">{{ item.label }}</div>
          <div class="text-xs text-muted-foreground">{{ item.email }}</div>
        </div>
      </div>
    </template>
  </AutoComplete>
</template>

远程搜索

<script setup lang="ts">
import { ref } from "vue";
import { AutoComplete } from "@reglow/reui";

const data = ref([]);
const loading = ref(false);

const handleSearch = (val: string) => {
  if (!val) {
    data.value = [];
    return;
  }
  loading.value = true;
  // 模拟远程请求
  setTimeout(() => {
    data.value = [
      { value: `${val}-1`, label: `${val} - 结果1` },
      { value: `${val}-2`, label: `${val} - 结果2` },
      { value: `${val}-3`, label: `${val} - 结果3` },
    ];
    loading.value = false;
  }, 1000);
};
</script>

<template>
  <AutoComplete
    :data="data"
    :loading="loading"
    placeholder="请输入关键字远程搜索"
    @search="handleSearch"
  />
</template>

尺寸

<template>
  <AutoComplete :data="[1, 2, 3]" size="small" placeholder="small" />
  <AutoComplete :data="[1, 2, 3]" size="default" placeholder="default" />
  <AutoComplete :data="[1, 2, 3]" size="large" placeholder="large" />
</template>

下拉位置

<template>
  <AutoComplete :data="data" position="top" placeholder="下拉在上方" />
  <AutoComplete :data="data" position="bottom" placeholder="下拉在下方" />
</template>

禁用

<template>
  <AutoComplete :data="[1, 2, 3]" disabled placeholder="禁用" />
</template>

校验状态

<template>
  <AutoComplete :data="[1, 2, 3]" validate-status="warning" placeholder="警告" />
  <AutoComplete :data="[1, 2, 3]" validate-status="error" placeholder="错误" />
</template>

默认高亮第一项

<template>
  <AutoComplete
    :data="data"
    default-active-first-option
    placeholder="打开后默认高亮第一项,回车选中"
  />
</template>

返回完整对象

设置 onSelectWithObjecttrueselect 事件返回完整对象。

<script setup lang="ts">
const onSelect = (item: any) => {
  console.log("选中对象:", item);
  // { value: "1", label: "张三", email: "..." }
};
</script>

<template>
  <AutoComplete
    :data="data"
    on-select-with-object
    @select="onSelect"
  />
</template>

前缀和后缀

<template>
  <AutoComplete :data="data" prefix="邮箱" suffix="@" />
</template>

自定义空内容

<template>
  <AutoComplete
    :data="[]"
    empty-content="暂无匹配结果"
    placeholder="输入搜索"
  >
    <template #emptyContent>
      <div class="py-4 text-center text-sm text-muted-foreground">
        <p>没有找到匹配项</p>
        <button class="text-primary hover:underline mt-1">创建新项</button>
      </div>
    </template>
  </AutoComplete>
</template>

加载中

<script setup lang="ts">
import { ref } from "vue";

const loading = ref(true);
</script>

<template>
  <AutoComplete :data="data" :loading="loading" placeholder="加载中..." />
</template>

清除按钮

<template>
  <AutoComplete :data="data" show-clear placeholder="可清除" />
</template>

受控

<script setup lang="ts">
import { ref } from "vue";

const value = ref("");
</script>

<template>
  <AutoComplete
    v-model:value="value"
    :data="data"
    placeholder="受控输入"
    @change="(val) => console.log(val)"
  />
</template>

API

Props

属性类型默认值说明
data(string | AutoCompleteItem)[][]候选项数据
valuestring | number-当前值(v-model:value)
defaultValuestring | number-默认值
placeholderstring-占位文字
disabledbooleanfalse是否禁用
sizesmall | default | largedefault尺寸
showClearbooleanfalse显示清除按钮
clearIconVNode-自定义清除按钮
loadingbooleanfalse加载中
motionbooleantrue动画
maxHeightnumber | string300下拉最大高度
positiontop | bottombottom下拉位置
emptyContentVNode | string-空内容
defaultActiveFirstOptionbooleanfalse默认高亮第一项
defaultOpenbooleanfalse默认展开
autoFocusbooleanfalse自动聚焦
prefixVNode | string-前缀
suffixVNode | string-后缀
validateStatusdefault | error | warningdefault校验状态
onSelectWithObjectbooleanfalse返回完整对象
dropdownClassNamestring-下拉类名
dropdownStyleCSSProperties-下拉样式
zIndexnumber1050z-index
classstring-附加类名

Events

事件说明回调参数
change输入变化/选中时(value: string | number)
search输入时(value: string)
select选中候选项(item: string | AutoCompleteItem)
focus获得焦点(e: FocusEvent)
blur失去焦点(e: FocusEvent)
keydown键盘按下(e: KeyboardEvent)

Slots

名称说明参数
default自定义候选项渲染{ item: AutoCompleteItem, index: number }
emptyContent自定义空内容-

类型

AutoCompleteItem:

属性类型说明
valuestring
labelstring显示标签

键盘操作

按键功能
/ 切换高亮选项
Enter选中高亮项(或打开面板)
Esc关闭面板

国际化

空状态文案默认跟随全局语言(zh-CN / zh-TW / en-US)。