Textarea 多行输入
多行文本输入。自动增高、字数统计、组合键提交。
基础用法
vue
<script setup>
import { ref } from 'vue'
const text = ref('')
</script>
<template>
<SrTextarea v-model="text" placeholder="请输入内容…" />
</template>自动增高
autosize 让高度随内容增长,maxRows 设上限——超过后转为内部滚动。
vue
<SrTextarea v-model="text" autosize :max-rows="5" />为什么必须有 maxRows
只设 autosize 而不设上限,用户粘贴一大段文本时输入框会撑到屏幕外, 把页面其他内容挤下去、提交按钮也找不到了。
上限之后转为内部滚动——这是唯一能让这类输入框「不失控」的方式。
不设 rows 且不用 autosize 时,默认显示 3 行。
vue
<SrTextarea v-model="fixed" :rows="5" />字数统计
show-count 显示「已输入 / 上限」。字数统计依赖 maxlength—— 没有上限时只显示已输入字数。
vue
<SrTextarea v-model="limited" :maxlength="100" show-count />
<SrTextarea v-model="text" show-count />字数统计按什么算
用 [...value].length 而非 value.length——后者会把一个 emoji 算成 2 个字符。
表情符号在 JS 字符串里通常占两个 UTF-16 码元,直接 .length 会得到 2。 用户看到的现象是「明明只输入了 10 个字,却提示 13/100」, 而且删掉一个 emoji 数字会跳 2。用展开运算符按码点计数才是用户直觉中的「字数」。
组合键提交
Cmd/Ctrl + Enter 提交。这是多行输入框的通行约定—— 回车用于换行,提交需要配合修饰键。
vue
<SrTextarea v-model="text" @submit="onSubmit" />提交后是否清空由宿主决定
组件不自动清空——有些场景(评论失败要重试、内容需要保留)不该清掉。 需要清空时在 @submit 里自己处理。
尺寸与状态
vue
<SrTextarea size="sm" />
<SrTextarea disabled />
<SrTextarea readonly />
<SrTextarea invalid />Props
| 名称 | 类型 | 默认值 | 说明 |
|---|---|---|---|
modelValue | string | '' | 当前值 |
size | 'sm' | 'md' | 'lg' | 'md' | 尺寸 |
placeholder | string | — | 占位文本 |
rows | number | 3 | 显示行数(autosize 时作为最小行数) |
autosize | boolean | false | 是否自动增高 |
maxRows | number | — | 自动增高的行数上限 |
maxlength | number | — | 最大字数 |
showCount | boolean | false | 是否显示字数统计 |
disabled | boolean | false | 是否禁用 |
readonly | boolean | false | 是否只读 |
invalid | boolean | false | 是否处于错误态 |
事件
| 事件 | 参数 | 说明 |
|---|---|---|
update:modelValue | string | 输入时 |
change | string | 原生 change 时机 |
submit | string | Cmd/Ctrl + Enter |
focus / blur | FocusEvent | 获得 / 失去焦点 |
无障碍
- 字数统计带
aria-live="polite",接近上限时读屏软件能播报余量 - 但不要每输入一个字就播报一次——那会打断用户。 实际做法是在接近上限(如剩余 10 字内)时才启用播报
- 焦点指示由容器的
:focus-within提供,与SrInput保持一致