表单
Input 单行输入
用于单行输入场景的 MoriUI 组件。
资源
导入
import { Input } from 'moriui'基础输入
Input 渲染原生 input,并通过 v-model 同步字符串值。
禁用状态
disabled 保留原生禁用语义;外围 Field 可使用 data-disabled 同步标签视觉。
无效状态
aria-invalid="true" 同时向辅助技术和 MoriUI 样式表达校验错误。
必填状态
required 保留原生必填校验语义,并应配合可见的必填提示。
RTL
输入内容、标签与占位符可继承或显式设置 dir。
示例
概览
密码输入、标签和安全说明。
密钥会加密保存。
<script setup lang="ts">
import { shallowRef } from 'vue'
import { Field, FieldDescription, FieldLabel, Input } from 'moriui'
const apiKey = shallowRef('')
</script>
<template>
<Field class="w-full max-w-xs">
<FieldLabel for="api-key">
API 密钥
</FieldLabel><Input
id="api-key"
v-model="apiKey"
type="password"
placeholder="sk-…"
/><FieldDescription>密钥会加密保存。</FieldDescription>
</Field>
</template>
基础
使用 v-model 同步字符串。
<script setup lang="ts">
import { Input } from 'moriui'
import { shallowRef } from 'vue'
const value = shallowRef('')
</script>
<template>
<Input v-model="value" aria-label="文本" placeholder="输入文本" />
</template>
字段
Field 提供标签与说明。
请选择唯一的用户名。
<script setup lang="ts">
import { shallowRef } from 'vue'
import { Field, FieldDescription, FieldLabel, Input } from 'moriui'
const username = shallowRef('')
</script>
<template>
<Field class="w-full max-w-xs">
<FieldLabel for="input-username">
用户名
</FieldLabel><Input id="input-username" v-model="username" placeholder="输入用户名" /><FieldDescription>请选择唯一的用户名。</FieldDescription>
</Field>
</template>
字段组
多个 Field 组成表单。
更新将发送到此地址。
<script setup lang="ts">
import { reactive } from 'vue'
import {
Button,
Field,
FieldDescription,
FieldGroup,
FieldLabel,
Input
} from 'moriui'
const form = reactive({ name: '', email: '' })
</script>
<template>
<FieldGroup class="w-full max-w-xs">
<Field>
<FieldLabel for="name">
姓名
</FieldLabel><Input id="name" v-model="form.name" placeholder="林晓" />
</Field><Field>
<FieldLabel for="email">
邮箱
</FieldLabel><Input
id="email"
v-model="form.email"
type="email"
placeholder="[email protected]"
/><FieldDescription>更新将发送到此地址。</FieldDescription>
</Field><Field orientation="horizontal">
<Button type="reset" variant="outline">
重置
</Button><Button type="submit">
提交
</Button>
</Field>
</FieldGroup>
</template>
禁用
disabled 保留原生不可交互语义。
此字段当前不可编辑。
<script setup lang="ts">
import { Field, FieldDescription, FieldLabel, Input } from 'moriui'
</script>
<template>
<Field data-disabled class="w-full max-w-xs">
<FieldLabel for="disabled-email">
邮箱
</FieldLabel><Input
id="disabled-email"
disabled
type="email"
placeholder="Email"
/><FieldDescription>此字段当前不可编辑。</FieldDescription>
</Field>
</template>
无效
aria-invalid 与 FieldError 同步错误。
请输入有效的邮箱地址。
<script setup lang="ts">
import { shallowRef } from 'vue'
import { Field, FieldError, FieldLabel, Input } from 'moriui'
const value = shallowRef('error@')
</script>
<template>
<Field data-invalid class="w-full max-w-xs">
<FieldLabel for="invalid-email">
邮箱
</FieldLabel><Input id="invalid-email" v-model="value" aria-invalid="true" /><FieldError>请输入有效的邮箱地址。</FieldError>
</Field>
</template>
文件
type="file" 使用浏览器文件选择能力。
选择一张图片上传。
<script setup lang="ts">
import { Field, FieldDescription, FieldLabel, Input } from 'moriui'
</script>
<template>
<Field class="w-full max-w-xs">
<FieldLabel for="picture">
图片
</FieldLabel><Input id="picture" accept="image/*" type="file" /><FieldDescription>选择一张图片上传。</FieldDescription>
</Field>
</template>
行内
横向 Field 组合搜索输入与按钮。
<script setup lang="ts">
import { shallowRef } from 'vue'
import { Button, Field, Input } from 'moriui'
const query = shallowRef('')
</script>
<template>
<Field class="w-full max-w-xs" orientation="horizontal">
<Input
v-model="query"
aria-label="搜索"
type="search"
placeholder="搜索…"
/><Button>搜索</Button>
</Field>
</template>
网格
并排组织姓名输入。
<script setup lang="ts">
import { reactive } from 'vue'
import { Field, FieldGroup, FieldLabel, Input } from 'moriui'
const name = reactive({ first: '', last: '' })
</script>
<template>
<FieldGroup class="grid w-full max-w-sm grid-cols-2">
<Field>
<FieldLabel for="first-name">
名
</FieldLabel><Input id="first-name" v-model="name.first" placeholder="晓" />
</Field><Field>
<FieldLabel for="last-name">
姓
</FieldLabel><Input id="last-name" v-model="name.last" placeholder="林" />
</Field>
</FieldGroup>
</template>
必填
required 与可见标记共同说明要求。
此字段必须填写。
<script setup lang="ts">
import { shallowRef } from 'vue'
import { Field, FieldDescription, FieldLabel, Input } from 'moriui'
const value = shallowRef('')
</script>
<template>
<Field class="w-full max-w-xs">
<FieldLabel for="required-input">
必填字段 <span aria-hidden="true" class="text-destructive">*</span>
</FieldLabel><Input id="required-input" v-model="value" required /><FieldDescription>此字段必须填写。</FieldDescription>
</Field>
</template>
徽记
标签内用 Badge 补充推荐信息。
<script setup lang="ts">
import { shallowRef } from 'vue'
import { Badge, Field, FieldLabel, Input } from 'moriui'
const url = shallowRef('')
</script>
<template>
<Field class="w-full max-w-xs">
<FieldLabel for="webhook">
Webhook 地址 <Badge variant="secondary">
推荐
</Badge>
</FieldLabel><Input
id="webhook"
v-model="url"
type="url"
placeholder="https://api.example.com/webhook"
/>
</Field>
</template>
输入组合
前缀、输入与图标共享输入边界。
https://
<script setup lang="ts">
import { shallowRef } from 'vue'
import { Info } from '@lucide/vue'
import {
Field,
FieldLabel,
InputGroup,
InputGroupAddon,
InputGroupInput,
InputGroupText
} from 'moriui'
const url = shallowRef('')
</script>
<template>
<Field class="w-full max-w-xs">
<FieldLabel for="website">
网站地址
</FieldLabel><InputGroup>
<InputGroupInput id="website" v-model="url" placeholder="example.com" /><InputGroupAddon><InputGroupText>https://</InputGroupText></InputGroupAddon><InputGroupAddon align="inline-end">
<Info />
</InputGroupAddon>
</InputGroup>
</Field>
</template>
按钮组合
Input 与提交按钮相邻排列。
<script setup lang="ts">
import { shallowRef } from 'vue'
import { Button, ButtonGroup, Field, FieldLabel, Input } from 'moriui'
const query = shallowRef('')
</script>
<template>
<Field class="w-full max-w-xs">
<FieldLabel for="button-search">
搜索
</FieldLabel><ButtonGroup>
<Input id="button-search" v-model="query" placeholder="输入关键词…" /><Button variant="outline">
搜索
</Button>
</ButtonGroup>
</Field>
</template>
表单
多个受控输入组成完整表单。
<script setup lang="ts">
import { reactive } from 'vue'
import {
Button,
Field,
FieldDescription,
FieldGroup,
FieldLabel,
Input
} from 'moriui'
const form = reactive({ name: '', email: '', phone: '', address: '' })
</script>
<template>
<form class="w-full max-w-sm">
<FieldGroup>
<Field>
<FieldLabel for="form-name">
姓名
</FieldLabel><Input id="form-name" v-model="form.name" required />
</Field><Field>
<FieldLabel for="form-email">
邮箱
</FieldLabel><Input id="form-email" v-model="form.email" type="email" /><FieldDescription>我们不会分享你的邮箱。</FieldDescription>
</Field><Field>
<FieldLabel for="form-phone">
电话
</FieldLabel><Input id="form-phone" v-model="form.phone" type="tel" />
</Field><Field>
<FieldLabel for="form-address">
地址
</FieldLabel><Input id="form-address" v-model="form.address" />
</Field><Field orientation="horizontal">
<Button type="button" variant="outline">
取消
</Button><Button type="submit">
提交
</Button>
</Field>
</FieldGroup>
</form>
</template>
RTL
阿拉伯语标签、说明与输入方向。
مفتاح API الخاص بك مشفر ومخزن بأمان.
<script setup lang="ts">
import { shallowRef } from 'vue'
import { Field, FieldDescription, FieldLabel, Input } from 'moriui'
const apiKey = shallowRef('')
</script>
<template>
<Field dir="rtl" class="w-full max-w-xs">
<FieldLabel for="rtl-api-key">
مفتاح API
</FieldLabel><Input
id="rtl-api-key"
v-model="apiKey"
dir="rtl"
type="password"
placeholder="sk-…"
/><FieldDescription>مفتاح API الخاص بك مشفر ومخزن بأمان.</FieldDescription>
</Field>
</template>
API
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| v-model | string | '' | 当前输入值。 |
| defaultValue | string | undefined | 未提供 v-model 时的初始值。 |
| 原生 input 属性 | InputHTMLAttributes | — | type、disabled、required、placeholder、aria-invalid 等自动透传到原生 input。 |
| class | HTMLAttributes["class"] | undefined | 合并到输入框变体类。 |
无障碍说明
Input 输出原生 input。调用方必须使用 Label/FieldLabel 或 aria-label 提供名称;错误使用 aria-invalid 和 FieldError,必填使用 required,文件输入保留浏览器原生选择与键盘行为。