| name | n-input |
| description | A versatile input component for text, password, and textarea inputs with comprehensive features including validation, icons, and various states |
| author | jiaiyan |
| version | 1.0.0 |
n-input Component
The n-input component is a versatile input field that supports text input, password input, and textarea modes. It provides comprehensive features for form handling, validation, and user interaction.
When to Use
Use n-input when you need to:
- Collect user text input in forms
- Create password fields with show/hide functionality
- Build multi-line text areas
- Add prefix/suffix icons or content to inputs
- Create input pairs (e.g., date range, value range)
- Display loading states during async operations
- Show validation status (success, warning, error)
Basic Usage
Text Input
<template>
<n-input v-model:value="value" type="text" placeholder="Basic Input" />
</template>
<script setup>
import { ref } from 'vue'
const value = ref('')
</script>
Textarea
<template>
<n-input
v-model:value="value"
type="textarea"
placeholder="Basic Textarea"
:rows="3"
/>
</template>
Different Sizes
<template>
<n-space vertical>
<n-input size="tiny" placeholder="Tiny Input" />
<n-input size="small" placeholder="Small Input" />
<n-input placeholder="Medium Input (default)" />
<n-input size="large" placeholder="Large Input" />
</n-space>
</template>
API Reference
Props
| Name | Type | Default | Description |
|---|
value / v-model:value | string | [string, string] | null | undefined | The input value. When pair is true, this is an array of two strings. |
type | 'text' | 'password' | 'textarea' | 'text' | Input type. |
size | 'tiny' | 'small' | 'medium' | 'large' | 'medium' | Input size. |
placeholder | string | [string, string] | undefined | Placeholder text. When pair is true, this is an array. |
disabled | boolean | false | Whether to disable the input. |
clearable | boolean | false | Whether the input is clearable. |
readonly | boolean | false | Set the readonly state. |
round | boolean | false | Use a rounded input style. |
maxlength | number | undefined | Maximum input length. |
minlength | number | undefined | Minimum input length. |
show-password-on | 'click' | 'mousedown' | undefined | The event to show the password (for password type). |
pair |
Events
| Name | Parameters | Description |
|---|
update:value | (value: string | [string, string]) | Triggered when value changes. |
input | (value: string | [string, string]) | Triggered on user input. |
change | (value: string | [string, string]) | Triggered on native change event. |
blur | () | Triggered when input loses focus. |
focus | () | Triggered when input gains focus. |
clear | () | Triggered when input is cleared. |
Slots
| Name | Parameters | Description |
|---|
prefix | () | Prefix content (e.g., icon). |
suffix | () | Suffix content (e.g., icon). |
password-invisible-icon | () | Custom icon when password is hidden. |
password-visible-icon | () | Custom icon when password is visible. |
clear-icon | () | Custom clear icon. |
separator | () | Custom separator content for pair inputs. |
count | { value: string } | Custom word count display. |
Methods
| Name | Type | Description |
|---|
focus | () => void | Focus the input element. |
blur | () => void | Remove focus from the input element. |
select | () => void | Select all text in the input. |
clear | () => void | Clear the input value. |
scrollTo | (options: { left?: number, top?: number, behavior?: 'auto' | 'smooth' }) => void | Scroll textarea content. |
Common Patterns
Password Input with Toggle
<template>
<n-input
v-model:value="password"
type="password"
show-password-on="mousedown"
placeholder="Enter password"
:maxlength="16"
/>
</template>
<script setup>
import { ref } from 'vue'
const password = ref('')
</script>
Input with Prefix and Suffix
<template>
<n-input v-model:value="value" placeholder="Search...">
<template #prefix>
<n-icon :component="SearchOutline" />
</template>
<template #suffix>
<n-icon :component="CloseCircleOutline" />
</template>
</n-input>
</template>
Loading State
<template>
<n-input
v-model:value="value"
:loading="isLoading"
placeholder="Loading state..."
/>
</template>
<script setup>
import { ref } from 'vue'
const value = ref('')
const isLoading = ref(true)
</script>
Pair Input (Range)
<template>
<n-input
v-model:value="range"
pair
separator="-"
:placeholder="['From', 'To']"
clearable
/>
</template>
<script setup>
import { ref } from 'vue'
const range = ref(['', ''])
</script>
Auto-resize Textarea
<template>
<n-input
v-model:value="value"
type="textarea"
:autosize="{ minRows: 3, maxRows: 6 }"
placeholder="Auto-resizing textarea"
/>
</template>
Input Validation with Status
<template>
<n-space vertical>
<n-input v-model:value="value" status="success" placeholder="Valid input" />
<n-input v-model:value="value" status="warning" placeholder="Warning" />
<n-input v-model:value="value" status="error" placeholder="Error" />
</n-space>
</template>
Limit Input Format
<template>
<n-input
v-model:value="value"
:allow-input="onlyAllowNumber"
placeholder="Numbers only"
/>
</template>
<script setup>
import { ref } from 'vue'
const value = ref('')
const onlyAllowNumber = (value) => {
return !value || /^\d+$/.test(value)
}
</script>
Using Methods via Ref
<template>
<n-space vertical>
<n-space>
<n-button @click="handleFocus">Focus</n-button>
<n-button @click="handleBlur">Blur</n-button>
<n-button @click="handleSelect">Select</n-button>
<n-button @click="handleClear">Clear</n-button>
</n-space>
<n-input ref="inputRef" v-model:value="value" placeholder="Control via methods" />
</n-space>
</template>
<script setup>
import { ref } from 'vue'
const inputRef = ref(null)
const value = ref('Hello World')
const handleFocus = () => inputRef.value?.focus()
const handleBlur = () => inputRef.value?.blur()
const handleSelect = () => inputRef.value?.select()
const handleClear = () => inputRef.value?.clear()
</script>
Best Practices
-
Use v-model:value for two-way binding: Always use v-model:value instead of separate value and @update:value for cleaner code.
-
Choose appropriate show-password-on: Use 'mousedown' for better UX (password visible while holding) or 'click' for toggle behavior.
-
Set loading to undefined when not loading: When using clearable with loading, set loading to undefined (not false) when not loading to avoid extra spacing.
-
Use allow-input for format validation: Prefer allow-input over manual validation for real-time input filtering.
-
Leverage input-props for native attributes: Use input-props to pass native HTML attributes like autocomplete, type="tel", etc.
-
Use count-graphemes for emoji support: For correct emoji/unicode character counting, provide a custom count-graphemes function.
-
Consider passively-activated for keyboard navigation: Use this when you want Tab to skip to the next focusable element without activating the input.
-
Use status prop for form validation: Display validation feedback using the status prop instead of custom styling.