Component

Vue Number Input Component

<DomNumberInput>

An accessible Vue 3 number input with v-model, labels, validation, and native min, max, and step constraints.

Use DomNumberInput when a Vue form needs a real numeric value with native browser spinbutton behavior. It works with Vue 3 v-model, emits numbers while the user types, and shares DOM Studio's accessible label, description, disabled, required, and error UI.

Quick start

Prompt your AI to add it

Paste this into your coding agent. It contains the package, imports, model, and constraints needed for a working Vue number input.

text
Add DOM Studio's Vue 3 number input to this project.

1. Install @getdom/studio.
2. Import DomNumberInput from '@getdom/studio/vue'.
3. Import '@getdom/studio/style.css' once in the app entry file if it is not already imported.
4. Add a ref named quantity and bind it with v-model.
5. Render a labelled Quantity field with min 1, max 99, and step 1.

Use the project's existing package manager and Vue conventions. Do not replace unrelated form code.

Quick start

Or add it manually in three steps

1. Install

Add the DOM Studio package to your Vue 3 project.

2. Load styles once

Import the complete stylesheet in your app entry file.

3. Import and bind

Import the component in any SFC and use ordinary v-model.

shell
npm install @getdom/studio
js
import '@getdom/studio/style.css';

Copy the smallest useful implementation

A ref, one import, v-model, and native numeric boundaries are enough.

Install
npm install @getdom/studio
vue
<script setup>
import '@getdom/studio/style.css';
import { ref } from 'vue';
import { DomNumberInput } from '@getdom/studio';

const quantity = ref(1);
</script>

<template>
	<div class="w-full max-w-sm">
		<DomNumberInput
			v-model="quantity"
			label="Quantity"
			description="Choose between 1 and 12 items."
			:min="1"
			:max="12"
		/>
		<p class="mt-3 text-sm text-muted-fg">Selected quantity: {{ quantity || 0 }}</p>
	</div>
</template>

Choose between 1 and 12 items.

Selected quantity: 1

Examples

Decimal steps and validation

Use step for fractional values. Native min and max constraints guide browser controls; pass your application errors through errors when you need an inline validation message.

A bounded percentage and a decimal number input with quarter-hour increments.

Whole numbers from 0 to 100.

Adjust in quarter-hour steps.

Install
npm install @getdom/studio
vue
<script setup>
import '@getdom/studio/style.css';
import { computed, ref } from 'vue';
import { DomNumberInput } from '@getdom/studio';

const completion = ref(75);
const hours = ref(1.5);
const completionErrors = computed(() => (
	completion.value === '' || completion.value < 0 || completion.value > 100
		? ['Enter a percentage from 0 to 100.']
		: []
));
</script>

<template>
	<div class="grid w-full max-w-xl gap-4 sm:grid-cols-2">
		<DomNumberInput
			v-model="completion"
			label="Completion percentage"
			description="Whole numbers from 0 to 100."
			:min="0"
			:max="100"
			:errors="completionErrors"
		/>
		<DomNumberInput
			v-model="hours"
			label="Estimated hours"
			description="Adjust in quarter-hour steps."
			:min="0"
			:step="0.25"
		/>
	</div>
</template>

Behavior

What value does v-model receive?

While filled

v-model receives a JavaScript number, so calculations do not need a separate string conversion.

When cleared

The value is an empty string. Treat that as missing input and validate it before saving.

Playground

Try the Vue number input

Number input playground

Change the label, description, value, min, max, step, disabled state, and validation props live.

Choose between 1 and 99 items.

Playground.vuevue
Install
npm install @getdom/studio
vue
<script setup>
import '@getdom/studio/style.css';
import { reactive } from 'vue';
import { DomNumberInput } from '@getdom/studio';

const data = reactive({
		"modelValue": 3,
		"id": "",
		"name": "",
		"label": "Quantity",
		"description": "Choose between 1 and 99 items.",
		"placeholder": "",
		"required": false,
		"disabled": false,
		"readOnly": false,
		"invalid": false,
		"errors": [],
		"visible": true,
		"validators": [],
		"validateOnBlur": true,
		"chrome": "field",
		"min": 1,
		"max": 99,
		"step": 1
	});
</script>

<template>
	<DomNumberInput
		v-bind="data"
		@update:modelValue="data.modelValue = $event"
	/>
</template>

Vue number input API

Props

Control props

NameTypeTSDefaultDescription
modelValuenumber | stringstring''Current numeric value.
minnumbernumber—Minimum accepted number and native spinbutton boundary.
maxnumbernumber—Maximum accepted number and native spinbutton boundary.
stepnumbernumber1Increment used by the browser spin buttons and arrow keys.

Field props

NameTypeTSDefaultDescription
idstringstring''Optional ID override. By default parent forms derive the input ID from the field path using underscores.
namestringstring''Local field name. Parent forms derive the full field path and native HTML name from the form hierarchy.
labelstringstring''Visible field label.
descriptionstringstring''Optional helper copy below the field.
placeholderstringstring''Placeholder shown when the control is empty.
requiredbooleanbooleanfalseMark the field as required.
disabledbooleanbooleanfalseDisable field interaction.
readOnlybooleanbooleanfalseShow the value but prevent editing.
invalidbooleanbooleanfalseMark the field invalid.
errors
ts
[
	{
		name: "Validation name",
		message: "Error message",
	}
]
array | object | stringArray<ErrorsItem
type ErrorsItem = {
	name?: string; // Name
	message?: string; // Message
};
>
[]Validation errors for this field.
visiblebooleanbooleantrueShow or hide the field.
validatorsarrayArray<unknown>[]Validators attached to this field. Use functions in Vue code, or serializable records such as { name: "minLength", props: { min: 2 } } in generated schemas.
validateOnBlurbooleanbooleantrueRun validators when the field loses focus.
chrome'field' | 'none' | falsestring'field'Render default field chrome, or hide chrome while keeping form state wiring.

Auto-generated from Vue number input.props and inline _edit hints.

Events

NamePayloadDescription
@update:modelValuenumber | stringFired with a number as the user types, or an empty string when cleared.
@focusFocusEventFired when the number input receives focus.
@blurFocusEventFired when the number input loses focus.

Names auto-detected from defineEmits and source emit() calls; payload and description from __doc.events when present.