表单

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-modelstring''当前输入值。
defaultValuestringundefined未提供 v-model 时的初始值。
原生 input 属性InputHTMLAttributestype、disabled、required、placeholder、aria-invalid 等自动透传到原生 input。
classHTMLAttributes["class"]undefined合并到输入框变体类。

无障碍说明

Input 输出原生 input。调用方必须使用 Label/FieldLabel 或 aria-label 提供名称;错误使用 aria-invalid 和 FieldError,必填使用 required,文件输入保留浏览器原生选择与键盘行为。

关联组件