Submission and reset
Submit with Form
Form renders a native <form>. It prevents the browser's page navigation on submit, calls form.submit, and handles native reset by calling form.reset.
<template>
<Form :form="form">
<!-- fields -->
<button
type="submit"
:disabled="form.isSubmitting"
>
{{ form.isSubmitting ? 'Saving...' : 'Save' }}
</button>
<button
type="reset"
:disabled="form.isSubmitting"
>
Reset
</button>
</Form>
</template>
What a submit does
- A submit while another is still running is ignored.
isSubmittingbecomestrue,submitCountincreases, and every field counts as touched.- The whole form is validated.
- If a value changed while validation was running, validation runs again on the new values.
- If the schema reports issues, they replace all errors and
onSubmitis not called.isSubmittedis stilltrue. - If validation passes, errors are cleared and
onSubmitis awaited with the validated output. isSubmittingbecomesfalseagain, even ifonSubmitthrows.
onSubmit can be sync or async. isSubmitting stays true for the whole duration, so you can use it to disable the button or show a spinner.
const form = useForm({
initialValues,
async onSubmit(data) {
await api.save(data) // data is SchemaOutput<typeof schema>
},
schema,
})
Errors thrown in onSubmit
If onSubmit throws or rejects, isSubmitting is reset and the error propagates out of form.submit().
- When
Formtriggers the submit, the rejection goes to Vue's error handler (app.config.errorHandler, orvue:errorin Nuxt) and your UI gets no error message. - When you call
form.submit()yourself, the returned promise rejects.
Handle expected failures inside onSubmit and turn them into form errors:
const form = useForm({
async onSubmit(data) {
try {
await api.save(data)
} catch {
form.setError({ message: 'We could not save your changes. Try again.' })
}
}
})
The Server errors recipe shows how to map field-level responses as well.
Submit programmatically
Call form.submit() when a submit does not start from <Form>, for example from a keyboard shortcut or a button outside the form element. It validates before invoking onSubmit.
await form.submit()
Passed a native submit event, it also calls preventDefault(). If you do not want to use Form, this is the equivalent markup:
<template>
<form
@submit="form.submit"
@reset.prevent="form.reset"
>
<!-- fields -->
</form>
</template>
Validate without submitting
form.validate() validates the whole form, updates form.errors, and does not call onSubmit.
const result = await form.validate()
if (result.issues) {
// show a message, scroll to the first error, etc.
} else {
result.value // parsed output
}
Reset the form
form.reset() returns the form to its baseline:
valuesreturn to the currentinitialValues;errorsreturn to the currentinitialErrors;- touched state and
submitCountare cleared, soisTouchedandisSubmittedbecomefalse; - pending debounced validations and in-flight validations are cancelled, along with any submit in progress;
- array items receive fresh identities, and
resetCountincreases.
Use type="reset" inside <Form>, or call form.reset() yourself.
Replace the baseline
Pass values, errors, or both to start from a new baseline. The values you supply replace the old baseline. They are not merged with it. An omitted argument keeps its current baseline.
form.reset(
{ email: 'jane@example.com' },
[{ message: 'Verify this address.', path: ['email'] }],
)
The next plain form.reset() returns to this new baseline. Use this when saved data should become the new starting point for dirty tracking. See Editing existing data.
Remount inputs after reset
form.resetCount increases on every reset. Use it as a :key on a subtree whose uncontrolled state should be discarded.
<template>
<MyThirdPartyEditor
:key="form.resetCount"
v-model="form.values.body"
/>
</template>
Reset after a successful submit
NotForm does not reset on its own after onSubmit. Do it when it suits your flow:
const form = useForm({
async onSubmit(data) {
await api.create(data)
form.reset() // back to a blank form
// or: form.reset(data) to make the saved data the new baseline
}
})
Next steps
- Form state lists every flag the form exposes.
- Server errors