Submit
Handle AutoForm's submit event, automatic and manual loading, validation errors and programmatic submission.
loadingAuto
When @submit returns a Promise, the submit button loading state is managed automatically by AutoForm (loadingAuto is enabled by default):
<script setup lang="ts">
import type { z } from 'zod'
const { afz } = useAutoForm()
const toast = useToast()
const schema = afz.object({
name: afz.string().min(2).meta({ label: '姓名' })
})
const state = reactive<Partial<z.output<typeof schema>>>({})
async function onSubmit() {
await new Promise(r => setTimeout(r, 1500))
toast.add({ title: '提交成功', description: 'loadingAuto 自动维护按钮 loading', color: 'success' })
}
</script>
<template>
<MAutoForm :schema="schema" :state="state" @submit="onSubmit" />
</template>
Manual Loading Control
Disable loading-auto and let submit-button-props.loading take over the button state:
<script setup lang="ts">
import type { z } from 'zod'
const { afz } = useAutoForm()
const toast = useToast()
const schema = afz.object({
name: afz.string().min(2).meta({ label: '姓名' })
})
const state = reactive<Partial<z.output<typeof schema>>>({})
const loading = ref(false)
async function onSubmit() {
loading.value = true
try {
await new Promise(r => setTimeout(r, 1500))
toast.add({ title: '提交成功(手动 loading)', color: 'success' })
}
finally {
loading.value = false
}
}
</script>
<template>
<MAutoForm
:schema="schema"
:state="state"
:loading-auto="false"
:submit-button-props="{ loading, label: loading ? '提交中…' : '提交' }"
@submit="onSubmit"
/>
</template>
Async Errors and Validation Events
Handle async errors in @submit; @error receives field validation failures:
<script setup lang="ts">
import type { z } from 'zod'
const { afz } = useAutoForm()
const toast = useToast()
const schema = afz.object({
name: afz.string().min(2).meta({ label: '姓名(最少 2 个字符)' })
})
const state = reactive<Partial<z.output<typeof schema>>>({})
async function onSubmit() {
try {
await new Promise((_, reject) => setTimeout(() => reject(new Error('API 返回 500')), 1000))
}
catch (e: unknown) {
const msg = e instanceof Error ? e.message : '未知错误'
toast.add({ title: '提交失败', description: msg, color: 'error' })
}
}
function onError() {
toast.add({ title: '校验未通过', description: '请检查字段输入', color: 'warning' })
}
</script>
<template>
<MAutoForm :schema="schema" :state="state" @submit="onSubmit" @error="onError" />
</template>
Programmatic Submit
Get the form instance via useTemplateRef, then trigger formRef.submit(), reset(), clear() externally (use :submit="false" to hide the built-in button):
<script setup lang="ts">
import type { z } from 'zod'
const { afz } = useAutoForm()
const toast = useToast()
const schema = afz.object({
name: afz.string().min(2).meta({ label: '姓名' }).default('默认值'),
age: afz.number().min(0).meta({ label: '年龄' })
})
const state = reactive<Partial<z.output<typeof schema>>>({})
const apiForm = useTemplateRef('apiForm')
async function onSubmit() {
await new Promise(r => setTimeout(r, 600))
toast.add({ title: '通过暴露 API 提交成功', color: 'success' })
}
</script>
<template>
<div class="flex flex-col gap-3">
<div class="flex flex-wrap gap-2">
<UButton size="sm" label="submit()" @click="apiForm?.formRef?.submit()" />
<UButton size="sm" variant="soft" label="reset()" @click="apiForm?.reset()" />
<UButton size="sm" variant="soft" color="neutral" label="clear()" @click="apiForm?.clear()" />
</div>
<MAutoForm ref="apiForm" :schema="schema" :state="state" :submit="false" @submit="onSubmit" />
</div>
</template>