AutoForm 允许你注册自定义 Vue 组件作为表单字段的渲染控件。这使得你可以扩展 AutoForm 的功能,使用任何 UI 组件库或自定义组件来渲染特定类型的字段。
自定义控件适用于以下场景:
通过 useAutoForm composable 注册自定义控件:
import { RichTextEditor } from '#components'
const { afz, controls } = useAutoForm({
// 注册控件类型为 'richtext'
richtext: {
component: RichTextEditor,
controlProps: { class: 'w-full' }
}
})
然后在 schema 中使用自定义控件:
const schema = afz.object({
content: afz
.string({
type: 'richtext', // 指定使用自定义控件
controlProps: {
readonly: false
}
})
.meta({
label: '文章内容',
description: '使用富文本编辑器编写文章内容'
})
})
最后将 controls 传递给 AutoForm 组件:
<MAutoForm
:schema="schema"
:state="form"
:controls="controls"
@submit="onSubmit"
/>
自定义控件组件需要满足以下要求:
v-model 绑定<script setup>
// 使用 defineModel (Vue 3.4+)
const modelValue = defineModel()
// 或使用 props + emit
const props = defineProps<{
modelValue: any
}>()
const emit = defineEmits<{
'update:modelValue': [value: any]
}>()
</script>
<script setup>
defineProps<{
modelValue: string
readonly?: boolean
placeholder?: string
// 其他自定义 props...
}>()
</script>
<script lang="ts" setup>
import type { FormSubmitEvent } from '@nuxt/ui'
import type { z } from 'zod/v4'
import { RichTextEditor } from '#components'
const toast = useToast()
const { afz, controls } = useAutoForm({
richtext: { component: RichTextEditor, controlProps: { class: 'w-full' } }
})
const schema = afz.object({
title: afz
.string({ controlProps: { placeholder: '请输入文章标题' } })
.min(1, '标题不能为空')
.meta({
label: '文章标题',
description: '请输入一个简洁明了的标题'
}),
category: afz
.enum(['tech', 'design', 'business', 'lifestyle'])
.default('tech')
.meta({
label: '分类',
description: '选择文章分类'
}),
content: afz
.string({
type: 'richtext',
controlProps: {
readonly: false
}
})
.min(10, '内容至少需要 10 个字符')
.meta({
label: '文章内容',
description: '使用富文本编辑器编写文章内容'
}),
tags: afz
.array(afz.string(), { type: 'inputTags' })
.default(['nuxt', 'vue'])
.meta({
label: '标签',
description: '添加相关标签'
}),
publishImmediately: afz
.boolean()
.default(false)
.meta({
label: '立即发布',
description: '勾选后文章将立即发布'
})
})
type Schema = z.output<typeof schema>
const form = ref<Partial<Schema>>({})
async function onSubmit(event: FormSubmitEvent<Schema>) {
toast.add({
title: '提交成功',
color: 'success',
description: '文章已保存,查看控制台输出。'
})
console.log('提交的数据:', event.data)
}
</script>
<template>
<UCard>
<MAutoForm
:schema="schema"
:state="form"
:controls="controls"
@submit="onSubmit"
/>
</UCard>
</template>
string()、number() 等),而不是控件类型。useAutoForm 中的 controlProps 和字段级别的 controlProps 会进行浅合并,字段级别的配置优先级更高。#components 自动导入,或手动导入组件。