开发预览 更新于 2026-05-10

Textarea 多行输入

多行输入 —— 与 Input 同色系,支持自动撑高、字符计数、resize 控制。

基础用法

视觉与 Input 共用一套色系。rows 控制初始行数,用户可以拖右下角调整高度。

背景 视口
src/App.vue
<script setup lang="ts">
import { ref } from 'vue';
import { CfTextarea } from '@chufix-design/vue';

const note = ref('');
</script>
<template>
  <CfTextarea v-model="note" placeholder="说点什么…" :rows="3" />
</template>
<script setup>
import { ref } from 'vue';
import { CfTextarea } from '@chufix-design/vue';

const note = ref('');
</script>
<template>
  <CfTextarea v-model="note" placeholder="说点什么…" :rows="3" />
</template>
import { useState } from 'react';
import { CfTextarea } from '@chufix-design/react';

export default function Demo() {
  const [note, setNote] = useState('');
  return (
    <>
      <CfTextarea value={note} onChange={setNote} placeholder="说点什么…" rows={3} />
    </>
  );
}
import { useState } from 'react';
import { CfTextarea } from '@chufix-design/react';

export default function Demo() {
  const [note, setNote] = useState('');
  return (
    <>
      <CfTextarea value={note} onChange={setNote} placeholder="说点什么…" rows={3} />
    </>
  );
}

视觉变体

outline 是默认描边,filled 提供浅色填充背景(密集表单常用),ghost 完全透明只在交互态显示边界。 与 Input 的同名变体一一对应,可以在同一个表单里混用而不破坏视觉一致性。

背景 视口
src/App.vue
<script setup lang="ts">
import { ref } from 'vue';
import { CfTextarea } from '@chufix-design/vue';

const a = ref<string>('');
const b = ref<string>('');
const c = ref<string>('');
</script>
<template>
  <div class="demo-stack">
    <CfTextarea v-model="a" variant="outline" placeholder="outline —— 默认描边" :rows="2" />
    <CfTextarea v-model="b" variant="filled"  placeholder="filled —— 浅色填充背景" :rows="2" />
    <CfTextarea v-model="c" variant="ghost"   placeholder="ghost —— 透明,只在 hover/focus 时可见" :rows="2" />
  </div>
</template>
<script setup>
import { ref } from 'vue';
import { CfTextarea } from '@chufix-design/vue';

const a = ref<string>('');
const b = ref<string>('');
const c = ref<string>('');
</script>
<template>
  <div class="demo-stack">
    <CfTextarea v-model="a" variant="outline" placeholder="outline —— 默认描边" :rows="2" />
    <CfTextarea v-model="b" variant="filled"  placeholder="filled —— 浅色填充背景" :rows="2" />
    <CfTextarea v-model="c" variant="ghost"   placeholder="ghost —— 透明,只在 hover/focus 时可见" :rows="2" />
  </div>
</template>
import { CfTextarea } from '@chufix-design/react';

export default function Demo() {
  return (
    <>
      <CfTextarea variant="outline" placeholder="outline" rows={2} />
      <CfTextarea variant="filled"  placeholder="filled"  rows={2} />
      <CfTextarea variant="ghost"   placeholder="ghost"   rows={2} />
    </>
  );
}
import { CfTextarea } from '@chufix-design/react';

export default function Demo() {
  return (
    <>
      <CfTextarea variant="outline" placeholder="outline" rows={2} />
      <CfTextarea variant="filled"  placeholder="filled"  rows={2} />
      <CfTextarea variant="ghost"   placeholder="ghost"   rows={2} />
    </>
  );
}

尺寸

3 档尺寸控制字号与内边距,与 Input 的 size 一致。表单中通常与同行 Input 保持一致。

背景 视口
src/App.vue
<script setup lang="ts">
import { ref } from 'vue';
import { CfTextarea } from '@chufix-design/vue';

const sm = ref<string>('');
const md = ref<string>('');
const lg = ref<string>('');
</script>
<template>
  <div class="demo-stack">
    <CfTextarea v-model="sm" size="sm" placeholder="size = sm(紧凑)" :rows="2" />
    <CfTextarea v-model="md" size="md" placeholder="size = md(默认)" :rows="2" />
    <CfTextarea v-model="lg" size="lg" placeholder="size = lg(宽松)" :rows="2" />
  </div>
</template>
<script setup>
import { ref } from 'vue';
import { CfTextarea } from '@chufix-design/vue';

const sm = ref<string>('');
const md = ref<string>('');
const lg = ref<string>('');
</script>
<template>
  <div class="demo-stack">
    <CfTextarea v-model="sm" size="sm" placeholder="size = sm(紧凑)" :rows="2" />
    <CfTextarea v-model="md" size="md" placeholder="size = md(默认)" :rows="2" />
    <CfTextarea v-model="lg" size="lg" placeholder="size = lg(宽松)" :rows="2" />
  </div>
</template>
import { CfTextarea } from '@chufix-design/react';

export default function Demo() {
  const sm = '';
  const md = '';
  const lg = '';
  return (
    <>
      <CfTextarea size="sm" placeholder="size = sm" rows={2} />
      <CfTextarea size="md" placeholder="size = md" rows={2} />
      <CfTextarea size="lg" placeholder="size = lg" rows={2} />
    </>
  );
}
import { CfTextarea } from '@chufix-design/react';

export default function Demo() {
  const sm = '';
  const md = '';
  const lg = '';
  return (
    <>
      <CfTextarea size="sm" placeholder="size = sm" rows={2} />
      <CfTextarea size="md" placeholder="size = md" rows={2} />
      <CfTextarea size="lg" placeholder="size = lg" rows={2} />
    </>
  );
}

状态

disabled 完全禁用、readonly 只读(可选中复制不能修改)、error 让边框与焦点环变红用于校验失败提示。

背景 视口
src/App.vue
<script setup lang="ts">
import { ref } from 'vue';
import { CfTextarea } from '@chufix-design/vue';

const a = ref<string>('禁用状态下不可输入也不可获取焦点');
const b = ref<string>('只读:可以选中复制,但不能修改');
const c = ref<string>('错误态:边框与焦点环都会变红,常用于校验失败');
</script>
<template>
  <div class="demo-stack">
    <CfTextarea v-model="a" disabled :rows="2" />
    <CfTextarea v-model="b" readonly :rows="2" />
    <CfTextarea v-model="c" error    :rows="2" />
  </div>
</template>
<script setup>
import { ref } from 'vue';
import { CfTextarea } from '@chufix-design/vue';

const a = ref<string>('禁用状态下不可输入也不可获取焦点');
const b = ref<string>('只读:可以选中复制,但不能修改');
const c = ref<string>('错误态:边框与焦点环都会变红,常用于校验失败');
</script>
<template>
  <div class="demo-stack">
    <CfTextarea v-model="a" disabled :rows="2" />
    <CfTextarea v-model="b" readonly :rows="2" />
    <CfTextarea v-model="c" error    :rows="2" />
  </div>
</template>
import { useState } from 'react';
import { CfTextarea } from '@chufix-design/react';

export default function Demo() {
  const [a, setA] = useState<string>('禁用状态下不可输入也不可获取焦点');
  const [b, setB] = useState<string>('只读:可以选中复制,但不能修改');
  const [c, setC] = useState<string>('错误态:边框与焦点环都会变红,常用于校验失败');
  return (
    <>
      <div className="demo-stack">
          <CfTextarea value={a} onChange={setA} disabled rows={2} />
          <CfTextarea value={b} onChange={setB} readonly rows={2} />
          <CfTextarea value={c} onChange={setC} error rows={2} />
        </div>
    </>
  );
}
import { useState } from 'react';
import { CfTextarea } from '@chufix-design/react';

export default function Demo() {
  const [a, setA] = useState<string>('禁用状态下不可输入也不可获取焦点');
  const [b, setB] = useState<string>('只读:可以选中复制,但不能修改');
  const [c, setC] = useState<string>('错误态:边框与焦点环都会变红,常用于校验失败');
  return (
    <>
      <div className="demo-stack">
          <CfTextarea value={a} onChange={setA} disabled rows={2} />
          <CfTextarea value={b} onChange={setB} readonly rows={2} />
          <CfTextarea value={c} onChange={setC} error rows={2} />
        </div>
    </>
  );
}

字符计数

maxlength 设上限(原生限制),show-count 在右下角显示当前字符数。超过上限会变红(虽然 maxlength 会先拦截)。

背景 视口
0 / 50
src/App.vue
<script setup lang="ts">
import { ref } from 'vue';
import { CfTextarea } from '@chufix-design/vue';

const bio = ref('');
</script>
<template>
  <CfTextarea
    v-model="bio"
    placeholder="个人简介(最多 50 字)"
    :rows="3"
    :maxlength="50"
    show-count
  />
</template>
<script setup>
import { ref } from 'vue';
import { CfTextarea } from '@chufix-design/vue';

const bio = ref('');
</script>
<template>
  <CfTextarea
    v-model="bio"
    placeholder="个人简介(最多 50 字)"
    :rows="3"
    :maxlength="50"
    show-count
  />
</template>
import { useState } from 'react';
import { CfTextarea } from '@chufix-design/react';

export default function Demo() {
  const [bio, setBio] = useState('');
  return (
    <>
      <CfTextarea value={bio} onChange={setBio} placeholder="个人简介(最多 50 字)" rows={3} maxlength={50} showCount />
    </>
  );
}
import { useState } from 'react';
import { CfTextarea } from '@chufix-design/react';

export default function Demo() {
  const [bio, setBio] = useState('');
  return (
    <>
      <CfTextarea value={bio} onChange={setBio} placeholder="个人简介(最多 50 字)" rows={3} maxlength={50} showCount />
    </>
  );
}

自动撑高

auto-resize 让框跟随内容增长,自动隐藏 resize 把手。适合不确定行数的场景(如评论、备注)。

背景 视口
src/App.vue
<script setup lang="ts">
import { ref } from 'vue';
import { CfTextarea } from '@chufix-design/vue';

const draft = ref('试着多敲几行回车,框会自动撑高,没有滚动条。\n这是第二行。');
</script>
<template>
  <CfTextarea
    v-model="draft"
    variant="filled"
    auto-resize
    placeholder="自动撑高的多行输入"
  />
</template>
<script setup>
import { ref } from 'vue';
import { CfTextarea } from '@chufix-design/vue';

const draft = ref('试着多敲几行回车,框会自动撑高,没有滚动条。\n这是第二行。');
</script>
<template>
  <CfTextarea
    v-model="draft"
    variant="filled"
    auto-resize
    placeholder="自动撑高的多行输入"
  />
</template>
import { useState } from 'react';
import { CfTextarea } from '@chufix-design/react';

export default function Demo() {
  const [draft, setDraft] = useState('试着多敲几行回车,框会自动撑高,没有滚动条。\n这是第二行。');
  return (
    <>
      <CfTextarea value={draft} onChange={setDraft} variant="filled" autoResize placeholder="自动撑高的多行输入" />
    </>
  );
}
import { useState } from 'react';
import { CfTextarea } from '@chufix-design/react';

export default function Demo() {
  const [draft, setDraft] = useState('试着多敲几行回车,框会自动撑高,没有滚动条。\n这是第二行。');
  return (
    <>
      <CfTextarea value={draft} onChange={setDraft} variant="filled" autoResize placeholder="自动撑高的多行输入" />
    </>
  );
}

Resize 控制

resize 决定用户拖拽时允许的方向。none 完全锁定,vertical 是默认行为,horizontal 仅横向,both 横纵都可拖。 当 auto-resize 开启时本属性会被覆盖为 none

背景 视口
src/App.vue
<script setup lang="ts">
import { ref } from 'vue';
import { CfTextarea } from '@chufix-design/vue';

const a = ref<string>('');
const b = ref<string>('');
const c = ref<string>('');
const d = ref<string>('');
</script>
<template>
  <div class="demo-stack">
    <CfTextarea v-model="a" resize="none"       placeholder="resize = none —— 完全锁定,无拖拽把手"       :rows="2" />
    <CfTextarea v-model="b" resize="vertical"   placeholder="resize = vertical —— 仅纵向可拖(默认)"      :rows="2" />
    <CfTextarea v-model="c" resize="horizontal" placeholder="resize = horizontal —— 仅横向可拖"           :rows="2" />
    <CfTextarea v-model="d" resize="both"       placeholder="resize = both —— 横纵都可拖"                 :rows="2" />
  </div>
</template>
<script setup>
import { ref } from 'vue';
import { CfTextarea } from '@chufix-design/vue';

const a = ref<string>('');
const b = ref<string>('');
const c = ref<string>('');
const d = ref<string>('');
</script>
<template>
  <div class="demo-stack">
    <CfTextarea v-model="a" resize="none"       placeholder="resize = none —— 完全锁定,无拖拽把手"       :rows="2" />
    <CfTextarea v-model="b" resize="vertical"   placeholder="resize = vertical —— 仅纵向可拖(默认)"      :rows="2" />
    <CfTextarea v-model="c" resize="horizontal" placeholder="resize = horizontal —— 仅横向可拖"           :rows="2" />
    <CfTextarea v-model="d" resize="both"       placeholder="resize = both —— 横纵都可拖"                 :rows="2" />
  </div>
</template>
import { CfTextarea } from '@chufix-design/react';

export default function Demo() {
  return (
    <>
      <CfTextarea resize="none"       placeholder="resize = none"       rows={2} />
      <CfTextarea resize="vertical"   placeholder="resize = vertical"   rows={2} />
      <CfTextarea resize="horizontal" placeholder="resize = horizontal" rows={2} />
      <CfTextarea resize="both"       placeholder="resize = both"       rows={2} />
    </>
  );
}
import { CfTextarea } from '@chufix-design/react';

export default function Demo() {
  return (
    <>
      <CfTextarea resize="none"       placeholder="resize = none"       rows={2} />
      <CfTextarea resize="vertical"   placeholder="resize = vertical"   rows={2} />
      <CfTextarea resize="horizontal" placeholder="resize = horizontal" rows={2} />
      <CfTextarea resize="both"       placeholder="resize = both"       rows={2} />
    </>
  );
}

API

Props

Prop类型默认值说明
modelValuestring''双向绑定值;React 端用 value + onChange
variant'outline' | 'filled' | 'ghost''outline'视觉变体,与 Input 一致
size'sm' | 'md' | 'lg''md'字号 / 内边距
rowsnumber3初始行数
placeholderstring占位文案
disabledbooleanfalse禁用
readonlybooleanfalse只读(可选中复制,不可修改;React 端 readOnly
errorbooleanfalse错误状态边框 / 焦点环
resize'none' | 'vertical' | 'horizontal' | 'both''vertical'用户拖拽 resize 行为
autoResizebooleanfalse内容增减时自动调整高度(覆盖 resize
maxlengthnumber字符上限(React 端为 maxLength
showCountbooleanfalse右下角显示字符计数

name / id 是直接透传到原生 <textarea> 的 HTML 标准属性,用于参与表单提交或 label 关联,使用方式与原生一致。

Events

Event载荷类型说明
update:modelValuestring输入触发,v-model 隐式监听
changestring原生 change 事件转发(失焦时)
focusFocusEvent获得焦点
blurFocusEvent失去焦点

反馈与讨论

Textarea 多行输入 的讨论

0
0 / 600
正在加载评论...