VTextarea
The VTextarea component provides a multi-line text input field with features like auto-grow, character counter, and validation.
Basic Usage
<template>
<VTextarea
v-model="message"
label="Message"
/>
</template>
<script setup>
import { ref } from 'vue'
const message = ref('')
</script>
The text value of the textarea.
Label text for the textarea.
rows
number | string
default:"5"
Number of rows to display.
Automatically grow the textarea to fit content.
Disable manual resizing of the textarea.
Maximum number of rows when auto-grow is enabled.
Maximum height in pixels when auto-grow is enabled.
counter
boolean | number | string
Display a character counter. Pass a number to set max length.
Function to compute the counter value.
Always show the counter instead of only when focused.
Always show the placeholder.
Text to prepend to the input.
Text to append to the input.
Add a clear icon to remove the text.
Make the textarea readonly.
Automatically focus the textarea when mounted.
Auto Grow
<template>
<VTextarea
v-model="message"
label="Auto-grow textarea"
auto-grow
rows="3"
max-rows="10"
/>
</template>
<script setup>
import { ref } from 'vue'
const message = ref('')
</script>
Character Counter
<template>
<div>
<!-- Simple counter -->
<VTextarea
v-model="message1"
label="With counter"
counter
/>
<!-- Counter with max length -->
<VTextarea
v-model="message2"
label="Max 100 characters"
:counter="100"
:rules="[v => v.length <= 100 || 'Max 100 characters']"
/>
<!-- Always visible counter -->
<VTextarea
v-model="message3"
label="Persistent counter"
counter
persistent-counter
/>
</div>
</template>
<script setup>
import { ref } from 'vue'
const message1 = ref('')
const message2 = ref('')
const message3 = ref('')
</script>
No Resize
<template>
<VTextarea
v-model="message"
label="Cannot be resized"
no-resize
rows="4"
/>
</template>
<script setup>
import { ref } from 'vue'
const message = ref('')
</script>
With Validation
<template>
<VForm>
<VTextarea
v-model="bio"
label="Biography"
:counter="200"
:rules="[
v => !!v || 'Bio is required',
v => v.length >= 10 || 'Bio must be at least 10 characters',
v => v.length <= 200 || 'Bio must be less than 200 characters'
]"
auto-grow
rows="3"
/>
</VForm>
</template>
<script setup>
import { ref } from 'vue'
const bio = ref('')
</script>
Custom Row Count
<template>
<div>
<VTextarea
v-model="message1"
label="3 rows"
rows="3"
/>
<VTextarea
v-model="message2"
label="10 rows"
rows="10"
/>
</div>
</template>
<script setup>
import { ref } from 'vue'
const message1 = ref('')
const message2 = ref('')
</script>
With Prefix and Suffix
<template>
<VTextarea
v-model="comment"
label="Comment"
prefix="Note:"
suffix="(optional)"
auto-grow
/>
</template>
<script setup>
import { ref } from 'vue'
const comment = ref('')
</script>
Auto Grow with Constraints
<template>
<VTextarea
v-model="message"
label="Constrained auto-grow"
auto-grow
rows="2"
max-rows="8"
hint="Grows from 2 to 8 rows"
persistent-hint
/>
</template>
<script setup>
import { ref } from 'vue'
const message = ref('')
</script>
Clearable
<template>
<VTextarea
v-model="message"
label="Clearable textarea"
clearable
auto-grow
/>
</template>
<script setup>
import { ref } from 'vue'
const message = ref('This text can be cleared')
</script>
Emitted when the textarea value changes.
update:focused
(focused: boolean) => void
Emitted when the focus state changes.
Emitted when the row count changes (auto-grow mode).
Emitted when the control area is clicked.
Emitted when mousedown occurs on the control area.
Customize the counter display.
Customize the details area (below the input).