组件/SearchInput 搜索输入框
通用组件

SearchInput 搜索输入框

基于输入框的搜索组件,内置搜索图标,并在 Enter 时触发 `search` 事件。

该页面由 AI 迁移生成,请谨慎使用

内容已迁移完成,但仍建议结合源码和人工评审结果使用。

SearchInput 搜索输入框

基于输入框的搜索组件,内置搜索图标,并在 Enter 时触发 search 事件。

如果你需要“像 Select 一样展开结果面板”的搜索框,推荐使用 SearchSelect

基础用法

SearchInput

示例即将加载...
<script setup lang="ts">
import { ref } from 'vue'

const value = ref('')
const last = ref('')
function onSearch(next: string) {
  last.value = next
}
</script>

<template>
  <div style="display: flex; flex-direction: column; gap: 12px; width: 420px;">
    <TxSearchInput
      v-model="value"
      placeholder="Search anything"
      @search="onSearch"
    />

    <div style="color: var(--tx-text-color-secondary); font-size: 12px;">
      value: {{ value }}
    </div>
    <div style="color: var(--tx-text-color-secondary); font-size: 12px;">
      last search: {{ last }}
    </div>
  </div>
</template>

远程搜索

SearchInput (remote)

示例即将加载...
<script setup lang="ts">
import { ref } from 'vue'

const value = ref('')
const loading = ref(false)
const hits = ref<string[]>([])
const open = ref(false)

async function onSearch(q: string) {
  const query = q.trim().toLowerCase()
  loading.value = true
  await new Promise(resolve => setTimeout(resolve, 200))
  hits.value = Array.from({ length: 12 })
    .map((_, i) => `Result ${i + 1}`)
    .filter(s => s.toLowerCase().includes(query))
  loading.value = false
  open.value = true
}

function onPick(h: string) {
  value.value = h
  open.value = false
}
</script>

<template>
  <div style="width: 320px;">
    <TxPopover v-model="open" :offset="6" :close-on-click-outside="true" :reference-full-width="true">
      <template #reference>
        <TxSearchInput
          v-model="value"
          remote
          :search-debounce="250"
          placeholder="Type to remote-search"
          @focus="open = true"
          @search="onSearch"
        />
      </template>

      <TxCard variant="solid" background="glass" shadow="soft" :radius="18" :padding="10">
        <div style="display: flex; flex-direction: column; gap: 8px;">
          <div style="font-size: 12px; color: var(--tx-text-color-secondary, #909399);">
            <span v-if="loading">Loading...</span>
            <span v-else>Hits: {{ hits.length }}</span>
          </div>

          <div style="display: flex; flex-direction: column; gap: 4px; max-height: 220px; overflow: auto;">
            <button
              v-for="h in hits"
              :key="h"
              type="button"
              style="text-align: left; padding: 8px 10px; border-radius: 12px; border: 1px solid transparent; background: transparent; cursor: pointer;"
              @click="onPick(h)"
            >
              {{ h }}
            </button>

            <div v-if="!loading && value.trim() && !hits.length" style="color: var(--tx-text-color-secondary, #909399); font-size: 12px; padding: 6px 2px;">
              No results
            </div>
          </div>
        </div>
      </TxCard>
    </TxPopover>
  </div>
</template>

API

TxSearchInput Props

属性名类型默认值说明
modelValuestring''输入值(v-model)
placeholderstring'Search'占位
disabledbooleanfalse禁用
clearablebooleantrue可清空
remotebooleanfalse是否远程搜索(输入时触发 search
searchDebouncenumber200远程搜索防抖(ms)

Events

事件名参数说明
update:modelValue(v: string)v-model 更新
input(v: string)输入
focus(e: FocusEvent)聚焦
blur(e: FocusEvent)失焦
clear-清空
search(v: string)Enter 或 remote 输入触发

Expose

名称类型说明
focus()() => void聚焦
blur()() => void失焦
clear()() => void清空
setValue(v)(v: string) => void设置值
getValue()() => string获取值