告别表单地狱:用 FormCreate 实现 Vue 动态表单的实战指南
还在为重复编写表单代码而头疼?本文将带你从零开始,用 FormCreate 构建一个完整的企业级动态表单系统。
一、为什么需要动态表单生成器?
在传统开发中,一个复杂表单的开发流程通常是:设计 UI → 编写 HTML 结构 → 添加校验规则 → 处理字段联动 → 调试样式兼容性 → 处理数据提交。这个过程不仅重复枯燥,而且当需求变更时,修改成本极高。 痛点场景示例:- 一个后台管理系统的用户信息编辑表单,包含 20+ 字段,需要联动校验
- 不同角色用户看到的表单字段不同,需要动态渲染
- 表单布局需要根据业务场景灵活调整
二、环境准备与项目初始化
1. 创建 Vue 项目
# 使用 Vite 创建 Vue 3 项目 npm create vite@latest form-create-demo -- --template vue cd form-create-demo npm install
2. 安装 FormCreate 及相关依赖
# 安装 FormCreate 核心库 npm install @form-create/element-ui # 安装 Element Plus(UI 框架) npm install element-plus @element-plus/icons-vue # 安装校验库(可选,FormCreate 内置了校验能力) npm install async-validator
3. 配置 Element Plus
在main.js中引入:
import { createApp } from 'vue'
import App from './App.vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
const app = createApp(App)
app.use(ElementPlus)
// 注册图标
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component)
}
app.mount('#app')
三、基础使用:快速创建第一个表单
1. 基本配置示例
创建一个简单的用户注册表单:<template>
<div class="form-container">
<form-create
:rule="rule"
:option="option"
@submit="onSubmit"
/>
</div>
</template>
<script setup>
import { ref } from 'vue'
import formCreate from '@form-create/element-ui'
const rule = ref([
{
type: 'input',
field: 'username',
title: '用户名',
value: '',
props: {
placeholder: '请输入用户名'
},
validate: [
{ required: true, message: '用户名不能为空' },
{ min: 3, max: 20, message: '用户名长度3-20个字符' }
]
},
{
type: 'input',
field: 'password',
title: '密码',
value: '',
props: {
type: 'password',
placeholder: '请输入密码'
},
validate: [
{ required: true, message: '密码不能为空' },
{ min: 6, message: '密码长度至少6位' }
]
},
{
type: 'select',
field: 'gender',
title: '性别',
value: '',
options: [
{ label: '男', value: 'male' },
{ label: '女', value: 'female' }
],
validate: [{ required: true, message: '请选择性别' }]
},
{
type: 'button',
title: '提交',
props: {
type: 'primary',
nativeType: 'submit'
}
}
])
const option = ref({
form: {
labelWidth: '80px'
},
submitBtn: false // 隐藏默认提交按钮
})
const onSubmit = (formData) => {
console.log('表单数据:', formData)
// 这里可以发送到后端
}
</script>
<style scoped>
.form-container {
max-width: 500px;
margin: 20px auto;
padding: 20px;
}
</style>
2. 核心配置项说明
| 配置项 | 说明 | 示例 |
|---|---|---|
type |
组件类型 | input、select、checkbox等 |
field |
字段名(提交时的 key) | username、password |
title |
标签文本 | '用户名' |
value |
默认值 | ''、[] |
props |
组件属性 | { placeholder: '请输入' } |
validate |
校验规则 | { required: true, message: '必填' } |
options |
选项数据(select/radio) | [{ label: '男', value: 'male' }] |
四、进阶实战:复杂业务场景处理
场景1:字段联动控制
需求:当用户选择"其他"选项时,显示额外的输入框const rule = ref([
{
type: 'select',
field: 'education',
title: '学历',
value: '',
options: [
{ label: '高中', value: 'high_school' },
{ label: '本科', value: 'bachelor' },
{ label: '硕士', value: 'master' },
{ label: '其他', value: 'other' }
],
on: {
// 监听值变化
change: (value) => {
// 动态控制其他字段的显示
formCreate.rule.show(value === 'other' ? 'otherEducation' : false)
}
}
},
{
type: 'input',
field: 'otherEducation',
title: '其他学历',
value: '',
hidden: true, // 默认隐藏
props: {
placeholder: '请输入其他学历'
},
validate: [
{
validator: (rule, value, callback) => {
// 只有当显示时才校验
if (!formCreate.rule.get('otherEducation').hidden && !value) {
callback(new Error('请输入其他学历'))
} else {
callback()
}
}
}
]
}
])
场景2:动态添加子表单
需求:用户可以动态添加多个工作经历const rule = ref([
{
type: 'group',
field: 'workExperience',
title: '工作经历',
children: [
{
type: 'input',
field: 'company',
title: '公司名称',
validate: [{ required: true }]
},
{
type: 'input',
field: 'position',
title: '职位',
validate: [{ required: true }]
}
]
},
{
type: 'button',
title: '添加经历',
props: {
type: 'default',
onClick: () => {
// 动态添加一组字段
formCreate.rule.push({
type: 'group',
field: `workExperience_${Date.now()}`,
children: [
{
type: 'input',
field: 'company',
title: '公司名称'
},
{
type: 'input',
field: 'position',
title: '职位'
}
]
})
}
}
}
])
场景3:自定义校验规则
需求:验证两次密码输入是否一致const rule = ref([
{
type: 'input',
field: 'password',
title: '密码',
props: { type: 'password' },
validate: [{ required: true }]
},
{
type: 'input',
field: 'confirmPassword',
title: '确认密码',
props: { type: 'password' },
validate: [
{ required: true, message: '请确认密码' },
{
validator: (rule, value, callback) => {
const password = formCreate.form.getFieldValue('password')
if (value !== password) {
callback(new Error('两次密码输入不一致'))
} else {
callback()
}
}
}
]
}
])
场景4:异步数据加载
需求:城市选择器需要从接口获取数据const rule = ref([
{
type: 'select',
field: 'city',
title: '城市',
value: '',
options: [],
on: {
// 组件挂载时加载数据
mounted: async () => {
try {
const response = await fetch('/api/cities')
const cities = await response.json()
formCreate.rule.update('city', {
options: cities.map(city => ({
label: city.name,
value: city.id
}))
})
} catch (error) {
console.error('加载城市数据失败:', error)
}
}
}
}
])
五、性能优化与最佳实践
1. 避免不必要的重新渲染
对于大型表单,频繁的重新渲染会影响性能。建议:// 使用 ref 包装配置,避免直接修改
const rule = ref(initialRule)
// 批量更新时使用 nextTick
import { nextTick } from 'vue'
const updateForm = async () => {
// 先隐藏表单
formCreate.option.hide = true
// 批量更新规则
rule.value = newRule
await nextTick()
formCreate.option.hide = false
}
2. 表单数据管理
对于复杂表单,建议使用状态管理库(如 Pinia)管理表单数据:// store/form.js
import { defineStore } from 'pinia'
export const useFormStore = defineStore('form', {
state: () => ({
formData: {}
}),
actions: {
updateField(field, value) {
this.formData[field] = value
},
async submitForm() {
// 提交逻辑
}
}
})
3. 错误处理与用户体验
const onSubmit = async (formData) => {
try {
const result = await api.submit(formData)
ElMessage.success('提交成功')
} catch (error) {
// 处理服务端校验错误
if (error.response?.data?.errors) {
formCreate.form.setErrors(error.response.data.errors)
} else {
ElMessage.error('提交失败,请重试')
}
}
}
六、常见问题与解决方案
Q1:如何获取表单实例?
// 在组件中 const formCreate = ref(null) // 在模板中 <form-create ref="formCreate" /> // 使用 formCreate.value.form.validate()
Q2:如何动态修改表单配置?
// 修改单个字段
formCreate.rule.update('username', {
props: { disabled: true }
})
// 批量更新
formCreate.rule.update([
{ field: 'field1', props: { disabled: true } },
{ field: 'field2', value: 'new value' }
])
Q3:如何重置表单?
// 重置所有字段 formCreate.form.resetFields() // 重置指定字段 formCreate.form.resetFields(['username', 'password'])
Q4:如何自定义组件?
// 注册自定义组件
formCreate.component('custom-input', {
props: ['value'],
emits: ['update:value'],
template: `
<input
:value="value"
@input="$emit('update:value', $event.target.value)"
/>
`
})
// 使用
{
type: 'custom-input',
field: 'customField'
}
七、总结
FormCreate 通过 JSON 配置的方式,将表单开发从"手写代码"转变为"配置驱动",带来了显著的效率提升。在实际项目中,建议:- 渐进式采用:可以先在简单表单中试用,再逐步应用到复杂场景
- 统一规范:团队内部制定表单配置规范,便于维护
- 结合可视化设计器:对于非技术人员,可以使用设计器工具生成配置
- 官方文档:https://www.form-create.com/Gitee
- 仓库:https://gitee.com/xaboy/form-create
- 在线演示:https://form-create.com/v3/example/
扩展阅读:
- 与 TypeScript 的集成实践

浙公网安备 33010602011771号