Input 输入框
单行输入 —— 3 种 variant、3 种尺寸、错误态、可清空、prefix/suffix。
基础用法
v-model / value + onChange 直接绑定字符串。placeholder 跟原生 input 一致。
背景
已输入:(空)
<script setup lang="ts">
import { ref } from 'vue';
import { CfInput } from '@chufix-design/vue';
const name = ref('');
</script>
<template>
<div class="demo-stack">
<CfInput v-model="name" placeholder="请输入用户名" />
<p class="demo-hint">已输入:<code>{{ name || '(空)' }}</code></p>
</div>
</template> <script setup>
import { ref } from 'vue';
import { CfInput } from '@chufix-design/vue';
const name = ref('');
</script>
<template>
<div class="demo-stack">
<CfInput v-model="name" placeholder="请输入用户名" />
<p class="demo-hint">已输入:<code>{{ name || '(空)' }}</code></p>
</div>
</template> import { useState } from 'react';
import { CfInput } from '@chufix-design/react';
export default function Demo() {
const [name, setName] = useState('');
return (
<CfInput
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="请输入用户名"
/>
);
} import { useState } from 'react';
import { CfInput } from '@chufix-design/react';
export default function Demo() {
const [name, setName] = useState('');
return (
<CfInput
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="请输入用户名"
/>
);
} 视觉变体
3 种 variant 提供不同的边框 / 背景强度。filled 适合表单密集的场景,ghost 在已有容器边框时使用,避免双重边框。
背景
<script setup lang="ts">
import { CfInput } from '@chufix-design/vue';
</script>
<template>
<div class="demo-stack">
<CfInput variant="outline" placeholder="outline · 默认" />
<CfInput variant="filled" placeholder="filled · 灰色填充" />
<CfInput variant="ghost" placeholder="ghost · 无边框,聚焦才出现" />
</div>
</template> <script setup>
import { CfInput } from '@chufix-design/vue';
</script>
<template>
<div class="demo-stack">
<CfInput variant="outline" placeholder="outline · 默认" />
<CfInput variant="filled" placeholder="filled · 灰色填充" />
<CfInput variant="ghost" placeholder="ghost · 无边框,聚焦才出现" />
</div>
</template> <CfInput variant="outline" placeholder="outline · 默认" />
<CfInput variant="filled" placeholder="filled · 灰色填充" />
<CfInput variant="ghost" placeholder="ghost · 无边框,聚焦才出现" /> <CfInput variant="outline" placeholder="outline · 默认" />
<CfInput variant="filled" placeholder="filled · 灰色填充" />
<CfInput variant="ghost" placeholder="ghost · 无边框,聚焦才出现" /> 尺寸
背景
<script setup lang="ts">
import { CfInput } from '@chufix-design/vue';
</script>
<template>
<div class="demo-stack">
<CfInput size="sm" placeholder="Small" />
<CfInput size="md" placeholder="Medium(默认)" />
<CfInput size="lg" placeholder="Large" />
</div>
</template> <script setup>
import { CfInput } from '@chufix-design/vue';
</script>
<template>
<div class="demo-stack">
<CfInput size="sm" placeholder="Small" />
<CfInput size="md" placeholder="Medium(默认)" />
<CfInput size="lg" placeholder="Large" />
</div>
</template> <CfInput size="sm" placeholder="Small" />
<CfInput size="md" placeholder="Medium" />
<CfInput size="lg" placeholder="Large" /> <CfInput size="sm" placeholder="Small" />
<CfInput size="md" placeholder="Medium" />
<CfInput size="lg" placeholder="Large" /> 状态
clearable 只在有值时显示清除按钮;error 切换到危险色边框 + ring;disabled / readonly 与原生 input 一致。
背景
<script setup lang="ts">
import { ref } from 'vue';
import { CfInput } from '@chufix-design/vue';
const search = ref('hello');
const email = ref('not-an-email');
const valid = (s: string) => /.+@.+\..+/.test(s);
</script>
<template>
<div class="demo-stack">
<CfInput v-model="search" clearable placeholder="可清空(输入后出现 ×)" />
<CfInput
v-model="email"
:error="!valid(email)"
placeholder="错误状态:邮箱格式不对"
/>
<CfInput placeholder="禁用" disabled />
<CfInput placeholder="只读" readonly model-value="readonly content" />
</div>
</template> <script setup>
import { ref } from 'vue';
import { CfInput } from '@chufix-design/vue';
const search = ref('hello');
const email = ref('not-an-email');
const valid = (s) => /.+@.+\..+/.test(s);
</script>
<template>
<div class="demo-stack">
<CfInput v-model="search" clearable placeholder="可清空(输入后出现 ×)" />
<CfInput
v-model="email"
:error="!valid(email)"
placeholder="错误状态:邮箱格式不对"
/>
<CfInput placeholder="禁用" disabled />
<CfInput placeholder="只读" readonly model-value="readonly content" />
</div>
</template> import { useState } from 'react';
import { CfInput } from '@chufix-design/react';
export default function Demo() {
const [email, setEmail] = useState('not-an-email');
const valid = /.+@.+\..+/.test(email);
return (
<>
<CfInput clearable placeholder="可清空(输入后出现 ×)" />
<CfInput
value={email}
onChange={(e) => setEmail(e.target.value)}
error={!valid}
placeholder="错误状态:邮箱格式不对"
/>
<CfInput placeholder="禁用" disabled />
<CfInput placeholder="只读" readOnly defaultValue="readonly content" />
</>
);
} import { useState } from 'react';
import { CfInput } from '@chufix-design/react';
export default function Demo() {
const [email, setEmail] = useState('not-an-email');
const valid = /.+@.+\..+/.test(email);
return (
<>
<CfInput clearable placeholder="可清空(输入后出现 ×)" />
<CfInput
value={email}
onChange={(e) => setEmail(e.target.value)}
error={!valid}
placeholder="错误状态:邮箱格式不对"
/>
<CfInput placeholder="禁用" disabled />
<CfInput placeholder="只读" readOnly defaultValue="readonly content" />
</>
);
} 前后缀
通过具名插槽(Vue)/ prefix & suffix props(React)放置图标或固定文本。clearable 和 suffix 互斥(有内容时显示清除按钮)。
背景
<script setup lang="ts">
import { ref } from 'vue';
import { CfInput } from '@chufix-design/vue';
const url = ref('');
const search = ref('');
</script>
<template>
<div class="demo-stack">
<CfInput v-model="url" placeholder="example">
<template #prefix>https://</template>
<template #suffix>.com</template>
</CfInput>
<CfInput v-model="search" clearable placeholder="搜索…">
<template #prefix>
<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.6">
<circle cx="7" cy="7" r="4" />
<path d="M10 10l3 3" stroke-linecap="round" />
</svg>
</template>
</CfInput>
</div>
</template> <script setup>
import { ref } from 'vue';
import { CfInput } from '@chufix-design/vue';
const url = ref('');
const search = ref('');
</script>
<template>
<div class="demo-stack">
<CfInput v-model="url" placeholder="example">
<template #prefix>https://</template>
<template #suffix>.com</template>
</CfInput>
<CfInput v-model="search" clearable placeholder="搜索…">
<template #prefix>
<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.6">
<circle cx="7" cy="7" r="4" />
<path d="M10 10l3 3" stroke-linecap="round" />
</svg>
</template>
</CfInput>
</div>
</template> <CfInput
value={url}
onChange={(e) => setUrl(e.target.value)}
placeholder="example"
prefix={<>https://</>}
suffix={<>.com</>}
/>
<CfInput
value={search}
onChange={(e) => setSearch(e.target.value)}
clearable
placeholder="搜索…"
prefix={<SearchIcon />}
/> <CfInput
value={url}
onChange={(e) => setUrl(e.target.value)}
placeholder="example"
prefix={<>https://</>}
suffix={<>.com</>}
/>
<CfInput
value={search}
onChange={(e) => setSearch(e.target.value)}
clearable
placeholder="搜索…"
prefix={<SearchIcon />}
/> API
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
modelValue | string | number | — | Vue v-model 绑定值 |
value | string | — | React 受控值 |
type | 'text' | 'password' | 'email' | 'number' | 'tel' | 'url' | 'search' | 'text' | 输入类型 |
variant | 'outline' | 'filled' | 'ghost' | 'outline' | 视觉变体 |
size | 'sm' | 'md' | 'lg' | 'md' | 高度与字号 |
clearable | boolean | false | 有值时显示清除按钮 |
error | boolean | false | 错误态边框 / ring |
disabled | boolean | false | 禁用 |
readonly | boolean | false | 只读 |
placeholder | string | — | 占位文本 |
反馈与讨论
Input 输入框 的讨论