Input 输入框

单行文本输入框。

<script setup lang="ts">
  import { ref } from 'vue'
  import { Mail } from '@lucide/vue'
  import { Input } from '@hina-ui/vue'

  const email = ref('shion@hoshimi.moe')
</script>

<template>
  <Input v-model="email" type="email" clearable aria-label="邮箱" class="w-72">
    <template #leading>
      <Mail />
    </template>
  </Input>
</template>
vue

用法

import { Input } from '@hina-ui/vue'
ts

输入框渲染为原生 input,v-model 绑定文本。未声明的属性都会传给 input,type、placeholder、maxlength、autocomplete 等属性照常可用。

<script setup lang="ts">
  import { ref } from 'vue'
  import { Input } from '@hina-ui/vue'

  const name = ref('')
</script>

<template>
  <Input v-model="name" aria-label="昵称" placeholder="昵称" class="w-72" />
</template>
vue

示例

附属内容

leading 与 trailing 插槽位于输入区两侧,用于放置图标、单位或者快捷键提示。每个插槽占一个与输入框等高的方格,内容居中。

kg
/
<script setup lang="ts">
  import { Mail } from '@lucide/vue'
  import { Input, Kbd, Stack } from '@hina-ui/vue'
</script>

<template>
  <Stack class="w-72">
    <Input type="email" aria-label="邮箱" placeholder="邮箱">
      <template #leading>
        <Mail />
      </template>
    </Input>
    <Input inputmode="decimal" aria-label="体重" placeholder="体重">
      <template #trailing>kg</template>
    </Input>
    <Input aria-label="快速跳转" placeholder="快速跳转">
      <template #trailing>
        <Kbd>/</Kbd>
      </template>
    </Input>
  </Stack>
</template>
vue

清除

clearable 在有内容时显示清除按钮,点击后清空并发出 clear 事件。

<script setup lang="ts">
  import { ref } from 'vue'
  import { Input } from '@hina-ui/vue'

  const keyword = ref('狼と香辛料')
</script>

<template>
  <Input v-model="keyword" clearable aria-label="关键词" placeholder="关键词" class="w-72" />
</template>
vue

加载中

loading 显示加载指示器。有 leading 插槽时顶替其中的图标,否则显示在末尾。

<script setup lang="ts">
  import { Mail } from '@lucide/vue'
  import { Input, Stack } from '@hina-ui/vue'
</script>

<template>
  <Stack class="w-72">
    <Input loading model-value="shion@hoshimi.moe" aria-label="校验邮箱中">
      <template #leading>
        <Mail />
      </template>
    </Input>
    <Input loading model-value="hoshimi" aria-label="校验昵称中" />
  </Stack>
</template>
vue

尺寸

sm 用于表格与工具栏,md 用于常规表单,lg 用于登录页等需要突出的场景。

<script setup lang="ts">
  import { Input, Stack } from '@hina-ui/vue'
</script>

<template>
  <Stack class="w-72">
    <Input size="sm" aria-label="小号" placeholder="小号" />
    <Input size="md" aria-label="中号" placeholder="中号" />
    <Input size="lg" aria-label="大号" placeholder="大号" />
  </Stack>
</template>
vue

形态

primary 带边框、背景与阴影;secondary 使用浅色背景;bare 背景透明,不绘制边框、阴影、悬停底色或容器聚焦环,尺寸与内边距仍由原有设置控制。

bare 保留禁用状态与 aria-invalid;错误信息可由 FormField 显示。附属按钮保留自身的悬停与键盘聚焦反馈。

<script setup lang="ts">
  import { Input, Stack } from '@hina-ui/vue'
</script>

<template>
  <Stack class="w-full max-w-xs">
    <Input variant="primary" aria-label="primary" placeholder="primary" />
    <Input variant="secondary" aria-label="secondary" placeholder="secondary" />
    <Input variant="bare" aria-label="bare" placeholder="bare" />
  </Stack>
</template>
vue

状态

invalid 标出校验未通过,disabled 不可编辑。

<script setup lang="ts">
  import { Input, Stack } from '@hina-ui/vue'
</script>

<template>
  <Stack class="w-72">
    <Input invalid model-value="shion@" aria-label="校验未通过" />
    <Input disabled model-value="hoshimi" aria-label="已禁用" />
  </Stack>
</template>
vue

在表单中

放进 FormField 后,标签通过 for 指向输入框,说明与错误信息由字段渲染并关联到它;校验规则、校验时机与提交交给 Form。

2 到 12 个字

<script setup lang="ts">
  import { reactive, ref } from 'vue'
  import * as v from 'valibot'
  import { Button, Form, FormField, Input, Text } from '@hina-ui/vue'

  const schema = v.object({
    name: v.pipe(
      v.string('请输入昵称'),
      v.nonEmpty('请输入昵称'),
      v.minLength(2, '昵称至少 2 个字'),
      v.maxLength(12, '昵称不超过 12 个字'),
    ),
  })

  const values = reactive({ name: '' })
  const saved = ref('')

  async function save(data: unknown) {
    await new Promise(resolve => setTimeout(resolve, 600))
    saved.value = JSON.stringify(data)
  }
</script>

<template>
  <Form v-slot="{ submitting }" :values="values" :rules="schema" class="w-80" @submit="save">
    <FormField name="name" label="昵称" description="2 到 12 个字" required>
      <Input v-model="values.name" />
    </FormField>
    <Button type="submit" :loading="submitting" class="self-start">保存</Button>
    <Text v-if="saved" tone="muted" size="sm">已保存:{{ saved }}</Text>
  </Form>
</template>
vue

行为

  • primary 与 secondary 悬停时填充加深,聚焦时显示强调色环,校验未通过时边框与环变为危险色;bare 不绘制这些外观。
  • 清除按钮只在有内容且未禁用时出现,点击后不会让输入区失焦。
  • 点击附属内容会聚焦输入区,起始处的把光标放到开头,末尾的放到末尾。
  • 附属内容、清除按钮与加载指示器的出现与消失都有过渡。

无障碍

  • 应当配合 label 元素或者 aria-label 提供名称。
  • 插槽中的图标是装饰性的,需要说明含义时给图标加 aria-label。
  • invalid 同时设置 aria-invalid,loading 同时设置 aria-busy。清除按钮的名称随语言包本地化。

API

Props

属性
类型
默认值
说明
modelValue
string
—
文本
clearable
boolean
false
是否显示清除按钮
loading
boolean
false
是否显示加载指示器
variant
'primary' | 'secondary' | 'bare'
'primary'
形态
size
'sm' | 'md' | 'lg'
'md'
尺寸
invalid
boolean
false
是否校验未通过
disabled
boolean
false
是否禁用
class
string
—
追加至根元素的类名

插槽

插槽
说明
leading
输入区起始处的附属内容
trailing
输入区末尾的附属内容

事件

事件
参数
说明
update:modelValue
value: string
文本变化
clear
—
文本被清空