Vue2企业级实战:构建智能表单配置化引擎
一、架构设计
基于JSON Schema+Vue动态组件+自定义指令的表单系统,支持100+表单元素的动态渲染
二、核心实现
1. 表单配置解析器
// form-engine.js
export default {
props: {
schema: {
type: Object,
required: true
},
model: {
type: Object,
required: true
}
},
render(h) {
const renderField = (field) => {
const componentMap = {
'input': 'el-input',
'select': 'el-select',
'checkbox': 'el-checkbox-group',
// 更多组件映射...
};
return h(componentMap[field.type], {
props: {
value: this.model[field.model],
...field.props
},
on: {
input: (val) => this.$set(this.model, field.model, val)
},
directives: [
{
name: 'validate',
value: field.rules
}
]
}, [
field.type === 'select' ?
field.options.map(opt =>
h('el-option', { props: { label: opt.label, value: opt.value } })
: null
]);
};
return h('div', this.schema.fields.map(renderField));
}
};
2. 验证指令系统
// validate.js
export default {
inserted(el, binding, vnode) {
const rules = binding.value;
const field = vnode.componentInstance;
field.$on('blur', () => {
const value = field.value;
const errors = [];
rules.forEach(rule => {
if (rule.required && !value) {
errors.push(rule.message || '必填字段');
}
if (rule.pattern && !rule.pattern.test(value)) {
errors.push(rule.message || '格式错误');
}
// 更多验证规则...
});
if (errors.length) {
field.$parent.$emit('validate-error', {
field: field.field,
errors
});
}
});
}
};
三、高级特性
1. 动态条件渲染
// 在form-engine.js中添加
watch: {
model: {
deep: true,
handler() {
this.schema.fields.forEach(field => {
if (field.showIf) {
const shouldShow = new Function(
'model',
`return ${field.showIf}`
)(this.model);
this.$set(field, '_visible', shouldShow);
}
});
}
}
},
// 修改renderField方法
const renderField = (field) => {
if (field._visible === false) return null;
// 原有渲染逻辑...
};
2. 表单设计器集成
// form-designer.vue
export default {
data() {
return {
currentSchema: {
fields: []
},
fieldTypes: [
{ label: '文本输入', value: 'input' },
{ label: '下拉选择', value: 'select' },
// 更多字段类型...
]
};
},
methods: {
addField(type) {
this.currentSchema.fields.push({
type,
model: `field_${Date.now()}`,
label: '新字段',
props: {},
rules: []
});
},
generateSchema() {
return JSON.parse(JSON.stringify(this.currentSchema));
}
}
};
四、完整案例
<template>
<div>
<form-engine
:schema="formSchema"
:model="formData"
@validate-error="handleError" />
<pre>{{ formData }}</pre>
</div>
</template>
<script>
export default {
data() {
return {
formSchema: {
fields: [
{
type: 'input',
model: 'username',
label: '用户名',
rules: [
{ required: true, message: '请输入用户名' },
{ pattern: /^[a-z0-9]+$/, message: '只能包含小写字母和数字' }
]
},
{
type: 'select',
model: 'gender',
label: '性别',
options: [
{ label: '男', value: 'male' },
{ label: '女', value: 'female' }
]
}
]
},
formData: {}
};
},
methods: {
handleError({ field, errors }) {
this.$message.error(`${field}验证失败: ${errors.join(',')}`);
}
}
};
</script>