Skip to content

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是否禁用booleanfalse
error是否为错误状态booleanfalse
maxLength最大长度;传入 errorOnly 时仅展示错误状态,不截断输入number | { length: number; errorOnly?: boolean }0
showWordLimit是否显示字数统计booleanfalse
allowClear是否允许清空booleanfalse
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使文本域失去焦点