提交

View source
处理 AutoForm 的提交事件、自动与手动 loading、校验错误以及编程式提交。

loadingAuto

@submit 返回 Promise 时,提交按钮的 loading 由 AutoForm 自动管理(loadingAuto 默认开启):

<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>

手动 loading 控制

关闭 loading-auto,由 submit-button-props.loading 接管按钮状态:

<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>

异常与校验事件

@submit 中处理异步异常;@error 接收字段校验失败:

<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>

编程式提交

通过 useTemplateRef 拿到表单实例后,可在外部触发 formRef.submit()reset()clear()(配合 :submit="false" 隐藏内置按钮):

<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>
Copyright © 2025 - 2026 YiXuan - MIT License