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 支持对象数组,每个对象需包含 value 和 label。

<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";
import { AutoComplete } from "@reglow/reui";

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<{ value: string; label: string }[]>([]);
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>

尺寸

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

const options = ["Apple", "Banana", "Cherry"];
</script>

<template>
  <div class="flex flex-col items-start gap-2">
    <AutoComplete :data="options" size="small" placeholder="small" />
    <AutoComplete :data="options" size="medium" placeholder="medium(默认)" />
    <AutoComplete :data="options" size="large" placeholder="large" />
  </div>
</template>

下拉位置

通过 position 控制下拉面板在上方或下方展示。

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

const options = ["选项 A", "选项 B", "选项 C"];
</script>

<template>
  <div class="flex flex-col items-start gap-2">
    <AutoComplete :data="options" position="top" placeholder="下拉在上方" />
    <AutoComplete :data="options" position="bottom" placeholder="下拉在下方" />
  </div>
</template>

禁用

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

const options = ["Apple", "Banana", "Cherry"];
</script>

<template>
  <AutoComplete :data="options" disabled placeholder="禁用" />
</template>

校验状态

通过 validate-status 展示 warning / error 状态样式。

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

const options = ["Apple", "Banana", "Cherry"];
</script>

<template>
  <div class="flex flex-col items-start gap-2">
    <AutoComplete :data="options" validate-status="warning" placeholder="警告" />
    <AutoComplete :data="options" validate-status="error" placeholder="错误" />
  </div>
</template>

默认高亮第一项

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

const options = ["Apple", "Banana", "Cherry"];
</script>

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

返回完整对象

设置 onSelectWithObject 为 true,select 事件返回完整对象。

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

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

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

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

前缀和后缀

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

const options = ["gmail.com", "163.com", "qq.com"];
</script>

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

自定义空内容

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

<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";
import { AutoComplete } from "@reglow/reui";

const loading = ref(true);
const options = ["Apple", "Banana", "Cherry"];
</script>

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

清除按钮

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

const options = ["Apple", "Banana", "Cherry"];
</script>

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

下拉箭头

默认显示右侧下拉箭头,点击可展开/收起下拉;通过 showArrow 可控制是否显示。

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

const options = ["Apple", "Banana", "Cherry"];
</script>

<template>
  <div class="flex flex-col items-start gap-2">
    <AutoComplete :data="options" placeholder="显示箭头(默认)" />
    <AutoComplete :data="options" :show-arrow="false" placeholder="不显示箭头" />
  </div>
</template>

受控

通过 v-model:value 受控管理输入值,change 事件在输入变化或选中时触发。

<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((domain) => `${val}@${domain}`)
    : [];
};
</script>

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

API

Props

属性类型默认值说明
data(string | AutoCompleteItem)[][]候选项数据
valuestring | number-当前值(v-model:value)
defaultValuestring | number-默认值
placeholderstring-占位文字
disabledbooleanfalse是否禁用
sizesmall | medium | large(default 为 medium 的旧写法别名)medium尺寸
showClearbooleanfalse显示清除按钮
clearIconVNode-自定义清除按钮
showArrowbooleantrue显示右侧下拉箭头(点击可展开/收起)
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)。