Textarea 文本域
用于多行文本输入,适合备注、描述、评论等较长内容。
何时使用
- 需要输入多行内容,例如备注、描述、审批意见、评论。
- 需要限制或提示字数,并在输入时展示统计。
- 需要根据内容自动调整高度。
- 需要在表单中展示禁用、只读、错误等状态。
基础用法
vue
<template>
<x-textarea v-model="value" placeholder="请输入描述" />
</template>
<script setup lang="ts">
import { ref } from 'vue';
const value = ref('用于搭建业务系统的 Vue 3 组件库');
</script>可清除
vue
<template>
<x-textarea v-model="value" allow-clear placeholder="请输入内容" />
</template>
<script setup lang="ts">
import { ref } from 'vue';
const value = ref('这段内容可以一键清空');
</script>字数统计
20/80
vue
<template>
<x-textarea
v-model="value"
:max-length="80"
show-word-limit
allow-clear
placeholder="请输入不超过 80 个字符"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const value = ref('Textarea 支持字数统计和清除操作');
</script>仅提示错误
19/20
vue
<template>
<x-textarea
v-model="value"
:max-length="{ length: 20, errorOnly: true }"
show-word-limit
allow-clear
/>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const value = ref('这段内容允许超出限制,但会进入错误状态');
</script>自适应高度
自适应高度会随内容增长,并在达到 maxRows 后出现滚动条。继续输入更多内容可以观察高度变化。
49/160
vue
<template>
<x-textarea
v-model="value"
:auto-size="{ minRows: 2, maxRows: 5 }"
:max-length="160"
show-word-limit
allow-clear
/>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const value = ref('自适应高度会随内容增长,并在达到 maxRows 后出现滚动条。');
</script>禁用与状态
12/20
vue
<template>
<x-textarea v-model="disabledValue" disabled />
<x-textarea v-model="readonlyValue" :textarea-attrs="{ readonly: true }" />
<x-textarea v-model="errorValue" error show-word-limit :max-length="20" />
</template>
<script setup lang="ts">
import { ref } from 'vue';
const disabledValue = ref('禁用状态不可编辑');
const readonlyValue = ref('只读状态通过 textareaAttrs 透传给原生 textarea');
const errorValue = ref('错误状态用于校验失败提示');
</script>后缀内容
备注
14/80
vue
<template>
<x-textarea v-model="value" :max-length="80" show-word-limit>
<template #suffix>
<span>备注</span>
</template>
</x-textarea>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const value = ref('审批备注需要更明确的填写状态');
</script>原生属性
vue
<template>
<x-textarea
v-model="value"
:textarea-attrs="{ rows: 4, name: 'description', required: true, autocomplete: 'off' }"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const value = ref('内部 textarea 可以接收 rows、name、required 等原生属性');
</script>自定义长度计算
22/20
vue
<template>
<x-textarea
v-model="value"
:max-length="20"
show-word-limit
:word-length="getMixedLength"
:word-slice="sliceMixedLength"
allow-clear
/>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const value = ref('中文算 2,English 算 1');
const getMixedLength = (value: string) =>
Array.from(value).reduce((total, char) => total + (char.charCodeAt(0) > 255 ? 2 : 1), 0);
const sliceMixedLength = (value: string, maxLength: number) => {
let total = 0;
let result = '';
for (const char of Array.from(value)) {
const next = total + (char.charCodeAt(0) > 255 ? 2 : 1);
if (next > maxLength) break;
total = next;
result += char;
}
return result;
};
</script>事件
17/80
vue
<template>
<x-textarea
v-model="value"
allow-clear
:max-length="80"
show-word-limit
@input="(value) => pushLog(`input: ${value.length}`)"
@change="(value) => pushLog(`change: ${value.length}`)"
@clear="() => pushLog('clear')"
@focus="() => pushLog('focus')"
@blur="() => pushLog('blur')"
/>
<div>
<div v-for="(log, index) in logs" :key="`${index}-${log}`">{{ log }}</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const value = ref('修改内容后失焦会触发 change');
const logs = ref<string[]>([]);
const pushLog = (message: string) => {
logs.value = [message, ...logs.value].slice(0, 5);
};
</script>按需导入
ts
import { Textarea } from 'x-next';Props
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
modelValue | 绑定值 | string | - |
defaultValue | 默认值,非受控模式 | string | '' |
placeholder | 占位提示 | string | - |
disabled | 是否禁用 | boolean | false |
error | 是否为错误状态 | boolean | false |
maxLength | 最大长度;传入 errorOnly 时仅展示错误状态,不截断输入 | number | { length: number; errorOnly?: boolean } | 0 |
showWordLimit | 是否显示字数统计 | boolean | false |
allowClear | 是否允许清空 | boolean | false |
autoSize | 是否自适应高度,可配置最小和最大行数 | boolean | { minRows?: number; maxRows?: number } | false |
wordLength | 自定义字符长度计算方法 | (value: string) => number | - |
wordSlice | 自定义超长截取方法,通常与 wordLength 一起使用 | (value: string, maxLength: number) => string | - |
textareaAttrs | 透传给内部 textarea 的原生属性 | Record<string, any> | - |
Events
| 事件名 | 说明 | 回调参数 |
|---|---|---|
update:modelValue | 值更新时触发 | value: string |
input | 用户输入时触发 | value: string, event: Event |
change | 文本域失焦且值变化时触发 | value: string, event: Event |
clear | 点击清除按钮时触发 | event: MouseEvent |
focus | 获取焦点时触发 | event: FocusEvent |
blur | 失去焦点时触发 | event: FocusEvent |
Slots
| 插槽名 | 说明 |
|---|---|
suffix | 后缀内容 |
Methods
| 方法 | 说明 |
|---|---|
focus | 使文本域获取焦点 |
blur | 使文本域失去焦点 |