Skip to content

Input 文本框 ​

v-model 双向绑定的单行输入框 / 多行文本框,默认是 outlined 样式:描边、浮动标签、可选的辅助文字与字数统计。

  • 标签悬停(浮动)由 CSS 完成:聚焦或有内容时,标签上浮到描边缺口处,缺口由 fieldset / legend 切出,不需要给标签加背景色,因此在任何页面背景上都正确。
  • variant="filled" 切换为浅色填充 + 底边的样式。
  • shape="pill" 换成胶囊形搜索栏:无描边、浅色填充、40px 高、两端全圆角。
  • 前置 / 尾部内容用 #leading / #trailing 插槽,也可以用 leadingIcon / trailingIcon 直接传图标数据。
  • type="password" 自带明文切换,clearable 自带清除按钮;传 validator 后,不通过时描边、标签、辅助文字与尾部图标一起切到错误样式。

基础用法 ​

必填

当前值:(空)

vue
<script setup lang="ts">
import { ref } from "vue";
import { Input } from "@sharpdotnut/dotsharp";

const name = ref("");
</script>

<template>
  <Input v-model="name" label="用户名" description="必填" />
</template>

label 会同时作为原生 <label for> 的名称;已经用 label 时不要再传 placeholder,否则两者会在未聚焦的空状态下重叠。

字数统计 ​

maxlength 会限制输入长度,并自动在辅助文字行的右侧显示 当前 / 上限。只想要计数、不限制长度时用 showCount。

2 / 100
vue
<script setup lang="ts">
import { ref } from "vue";
import { Input } from "@sharpdotnut/dotsharp";

const amount = ref("55");
</script>

<template>
  <Input v-model="amount" label="金额" :maxlength="100" />
</template>

前置与尾部内容 ​

#leading 和 #trailing 接受任意内容:图标、图片、按钮、下拉箭头,或完全自定义的排版。

vue
<script setup lang="ts">
import { ref } from "vue";
import { Input } from "@sharpdotnut/dotsharp";
import mic from "@iconify-icons/material-symbols/mic";
import search from "@iconify-icons/material-symbols/search";

const searchText = ref("");
</script>

<template>
  <Input v-model="searchText" label="搜索" :leading-icon="search" :trailing-icon="mic" />
</template>

插槽优先于同名图标属性,适合放图片或交互控件:

vue
<script setup lang="ts">
import { ref } from "vue";
import { Icon, Input } from "@sharpdotnut/dotsharp";
import expandMore from "@iconify-icons/material-symbols/expand-more";

const email = ref("[email protected]");
</script>

<template>
  <Input v-model="email" label="邮箱">
    <template #trailing>
      <button type="button" aria-label="选择邮箱">
        <Icon :icon="expandMore" />
      </button>
    </template>
  </Input>
</template>
  • 前置内容固定占 1.5rem 宽并居中,浮动标签据此对齐描边缺口;放图片时用 class="h-6 w-6 rounded-full" 之类的尺寸。
  • 尾部内容宽度自适应,不参与标签排版,可以放心放长文本或按钮。
  • 图标建议继续用 Icon(见 Icon 图标),直接传 @iconify-icons/material-symbols 的图标数据。

清除与密码可见性 ​

clearable 在有内容时显示清除按钮,点击后把模型设为 ""、回焦输入框并触发 clear 事件。type="password" 默认带明文切换按钮;revealable="false" 可关闭。

vue
<script setup lang="ts">
import { ref } from "vue";
import { Input } from "@sharpdotnut/dotsharp";

const password = ref("secret123");
</script>

<template>
  <Input v-model="password" type="password" label="密码" clearable />
</template>

type 直通原生 input:text、email、number、search、tel、url 等都能用;number 下模型读到的仍是字符串。

自动完成 ​

autocomplete 是原生属性名,因此候选函数用 suggest:它接收当前输入文本,同步返回候选文本数组,渲染为与 Select / Menu 同一套规格的弹层(elevated 底色、4px 圆角、阴影、48px 行高)。

当前值:黑

vue
<script setup lang="ts">
import { ref } from "vue";
import { Input } from "@sharpdotnut/dotsharp";

const fruit = ref("黑");
const fruits = ["苹果", "杏", "香蕉", "黑莓", "蓝莓", "樱桃", "葡萄", "桃"];

function suggestFruit(input: string): string[] {
  const keyword = input.trim().toLowerCase();
  if (!keyword) return fruits;
  return fruits.filter((item) => item.toLowerCase().includes(keyword));
}
</script>

<template>
  <Input v-model="fruit" label="水果" :suggest="suggestFruit" clearable />
</template>
  • 聚焦或输入时打开,函数返回空数组、Escape、Tab 或点击外部时收起;用代码改 v-model 不会弹出候选栏。
  • 键盘遵循 ARIA combobox 模式:↓ / ↑ 移动高亮、Enter 采用高亮项、Escape 收起;没有高亮项时 Enter 仍按原生行为提交。
  • 选中后模型被替换为候选文本,并触发 select 事件;候选栏宽度与输入框一致,视口下方空间不足时向上展开。
  • 只对单行文本框生效(textarea 忽略);disabled / readonly 下不弹出。原生 autocomplete 属性仍照常透传给 <input>。

多行文本 ​

textarea 渲染为 <textarea>,rows 控制初始行数,maxlength / showCount / clearable 等行为保持一致。多行时标签总是浮在描边缺口上。

最多 120 个字符0 / 120
vue
<script setup lang="ts">
import { ref } from "vue";
import { Input } from "@sharpdotnut/dotsharp";

const note = ref("");
</script>

<template>
  <Input
    v-model="note"
    textarea
    label="备注"
    :rows="3"
    :maxlength="120"
    description="最多 120 个字符"
  />
</template>

Filled 变体 ​

filled 变体
vue
<script setup lang="ts">
import { ref } from "vue";
import { Input } from "@sharpdotnut/dotsharp";

const filled = ref("晓雨");
</script>

<template>
  <Input v-model="filled" variant="filled" label="名称" description="filled 变体" />
</template>

filled 的标签固定在填充区顶部,聚焦时底边加粗,不使用 fieldset 缺口。

胶囊搜索栏 ​

shape="pill" 换成胶囊形搜索栏:去掉描边、改用 --ds-surface-hover 填充、高度 40px、两端全圆角;聚焦与校验不通过用 ring 表示,不改变盒子尺寸。多行(textarea)时忽略该属性。

vue
<script setup lang="ts">
import { ref } from "vue";
import { Input } from "@sharpdotnut/dotsharp";

const searchText = ref("");
</script>

<template>
  <Input v-model="searchText" shape="pill" type="search" placeholder="搜索" />
</template>
  • 胶囊形没有标签缺口:label 不渲染成可见标签,只作为 aria-label 提供给读屏,视觉提示交给 placeholder。
  • 胶囊形下 variant 不生效(既不画描边,也不加底边)。

表单校验 ​

validator 接收当前值,返回 false 表示通过;返回 true 或错误文案表示不通过。默认在输入与失焦时各校验一次,用 validateOn 调整;控件还暴露 validate() / clearValidate()。

vue
<script setup lang="ts">
import { ref } from "vue";
import { Input } from "@sharpdotnut/dotsharp";

const username = ref("aurora");
const usernameValidator = (value: string | number) =>
  String(value).trim().length >= 2 ? false : "用户名至少 2 个字符";
</script>

<template>
  <Input v-model="username" label="用户名" :validator="usernameValidator" />
</template>

不通过时描边、标签、辅助文字与尾部错误图标一起切到错误样式,错误文案优先使用验证函数返回的字符串。放在 Form / FormItem 里时,Form.validate() 会一起校验;完整约定见表单指南。

API ​

属性 ​

属性类型默认值说明
v-modelstring | number""绑定值
variant"outlined" | "filled""outlined"容器样式
shape"default" | "pill""default"容器形状;pill 为 40px 胶囊形搜索栏(多行忽略)
labelstring—浮动标签,同时作为控件的可访问名称
floatLabelbooleanfalse标签始终上浮;默认仅在聚焦或有内容时上浮
typestring"text"原生 input 类型
disabledbooleanfalse禁用
readonlybooleanfalse只读
textareabooleanfalse渲染为多行 <textarea>
rowsnumber3textarea 的初始行数
clearablebooleanfalse有内容时显示清除按钮
revealablebooleantruetype="password" 时显示明文切换按钮
leadingIconIconifyIcon | string—前置图标;#leading 插槽优先
trailingIconIconifyIcon | string—尾部图标;#trailing 插槽优先
descriptionstring—辅助文字
validator(value) => boolean | string—验证函数:false 通过,true / 字符串不通过
validateOn"input" | "blur" | ("input" | "blur")[]["input", "blur"]自动校验时机;传 [] 关闭自动校验
maxlengthnumber—最大长度,同时自动开启字数统计
showCountbooleanfalse只显示字数统计、不限制长度
suggest(input: string) => string[]—自动完成候选函数;返回空数组时收起候选栏

插槽 ​

插槽说明
leading输入框前置内容,固定 1.5rem 宽并居中,通常是图标或头像图片
trailing输入框尾部内容,宽度自适应,可放图标、图片、下拉箭头或自定义按钮

事件 ​

事件说明
update:modelValue输入值变化
clear点击清除按钮,模型已被重置为 "" 之后触发
select从自动完成候选栏选中一项,模型已更新之后触发

可访问性 ​

  • label 通过 for 关联控件;校验不通过时控件带 aria-invalid。
  • 辅助文字 / 错误信息会被控件的 aria-describedby 引用。
  • 清除与明文切换是原生 button,带 aria-label;明文切换同时维护 aria-pressed。
  • 提供 suggest 时控件是 role="combobox" + aria-autocomplete="list",通过 aria-expanded / aria-controls / aria-activedescendant 关联候选栏(role="listbox" 与 role="option")。
  • 根元素是 div:class / style 作用在根元素上,其余属性与事件(id、name、autocomplete、inputmode、@blur 等)透传给内部 input / textarea。