1. 定义表单项组件
- 自定义文本输入框
- 自定义开关选择器
<template>
<a-input style="width: 100%;" v-model="childVal" @blur="handleChildBlur"></a-input>
</template>
<script>
export default {
name: "AiKanCustomInput",
props: {
fatherVal: String
},
// 2.2新增 在组件内定义 指定父组件调用时候的传值属性和事件类型
model: {
prop: "fatherVal",
event: "handleChildValueChange"
},
data() {
return {
childVal: this.fatherVal
}
},
methods: {
handleChildBlur() {
// 通过model属性设置,这样就可以修改父组件v-model绑定的值
this.$emit("handleChildValueChange", this.childVal);
}
}
}
</script>
<template>
<a-switch v-model="childVal" @change="handleChildSelectChange"/>
</template>
<script>
export default {
name: "AiKanCustomSwitch",
props: {
fatherVal: Boolean,
},
// 2.2新增 在组件内定义 指定父组件调用时候的传值属性和事件类型
model: {
prop: "fatherVal",
event: "handleChildValueChange"
},
data() {
return {
childVal: this.fatherVal
}
},
methods: {
handleChildSelectChange() {
// 通过model属性设置,这样就可以修改父组件v-model绑定的值
this.$emit("handleChildValueChange", this.childVal);
}
}
}
</script>
利用model属性,可以让父组件绑定值和子组件绑定值进行双向绑定;做到子组件值变化,父组件值也跟着变化
2. 定义表单并引用表单项组件
<template>
<a-modal :visible="visible" :title="'动态表单编辑Modal'" :width="1000" @ok="handleSubmit" @cancel="handleCancel">
<a-form-model ref="form" :model="form">
<a-form-model-item v-for="field in formFields" :label="field.label" :prop="field.prop" :labelCol="labelCol" :wrapperCol="wrapperCol">
<component :is="field.componentType" v-model="form[field.prop]" :fatherVal="form[field.prop]"/>
</a-form-model-item>
</a-form-model>
</a-modal>
</template>
<script>
import AiKanCustomInput from "./modules/AiKanCustomInput";
import AiKanCustomSwitch from "./modules/AiKanCustomSwitch";
const form_fields = [
{
label: '姓名',
prop: 'name',
componentType: 'ai-kan-custom-input'
},
{
label: '是否删除',
prop: 'delFlag',
componentType: 'ai-kan-custom-switch'
}
];
export default {
name: "AiKanFormModal",
components: {
AiKanCustomSwitch,
AiKanCustomInput
},
data() {
return {
labelCol: {
xs: { span: 24 },
sm: { span: 5 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 16 },
},
formFields: form_fields,
visible: false,
form: {},
}
},
methods: {
handleSubmit() {
console.log("====" + JSON.stringify(this.form));
},
handleCancel() {
this.visible = false;
},
}
}
</script>
这样就可以通过定义js对象数组form_fields来动态自定义表单内容
效果如下:

当我们提交表单时,form数据也是自动填充了

3. 增加表单校验
- 模式一,validateRules数据格式如下:
const validateRules = {
'name': {required: true, pattern: /^[a-zA-Z]{3,6}$/},
'delFlag': {required: true},
};
<template>
<a-modal :visible="visible" :title="'动态表单编辑Modal'" :width="1000" @ok="handleSubmit" @cancel="handleCancel">
<a-form-model ref="form" :model="form" :rules="validateRules">
<a-form-model-item v-for="field in formFields" :label="field.label" :prop="field.prop" :labelCol="labelCol" :wrapperCol="wrapperCol">
<component :is="field.componentType" v-model="form[field.prop]" :fatherVal="form[field.prop]"/>
</a-form-model-item>
</a-form-model>
</a-modal>
</template>
<script>
import AiKanCustomInput from "./modules/AiKanCustomInput";
import AiKanCustomSwitch from "./modules/AiKanCustomSwitch";
const form_fields = [
{
label: '姓名',
prop: 'name',
componentType: 'ai-kan-custom-input'
},
{
label: '是否删除',
prop: 'delFlag',
componentType: 'ai-kan-custom-switch'
}
];
const validateRules = {
'name': {required: true, pattern: /^[a-zA-Z]{3,6}$/},
'delFlag': {required: true},
};
export default {
name: "AiKanFormModal",
components: {
AiKanCustomSwitch,
AiKanCustomInput
},
data() {
return {
labelCol: {
xs: { span: 24 },
sm: { span: 5 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 16 },
},
formFields: form_fields,
validateRules: validateRules,
visible: false,
form: {},
}
},
methods: {
handleSubmit() {
this.$refs.form.validate(valid => {
if (valid) {
console.log("====验证成功," + JSON.stringify(this.form));
} else {
console.log("====验证失败," + JSON.stringify(this.form));
}
})
},
handleCancel() {
this.visible = false;
},
}
}
</script>
- 模式二,校验规则数据在form_fields里面,则需将rules定义在a-form-model-item上,并编写validateFields对formItem进行验证,格式如下:
const form_fields = [
{
label: '姓名',
prop: 'name',
componentType: 'ai-kan-custom-input',
validateRule: {required: true, pattern: /^[a-zA-Z]{3,6}$/}
},
{
label: '是否删除',
prop: 'delFlag',
componentType: 'ai-kan-custom-switch',
validateRule: {required: true}
}
];
<template>
<a-modal :visible="visible" :title="'动态表单编辑Modal'" :width="1000" @ok="handleSubmit" @cancel="handleCancel">
<a-form-model ref="form" :model="form">
<a-form-model-item v-for="field in formFields" :label="field.label" :prop="field.prop" :labelCol="labelCol" :wrapperCol="wrapperCol" :rules="field.validateRule">
<component :is="field.componentType" v-model="form[field.prop]" :fatherVal="form[field.prop]"/>
</a-form-model-item>
</a-form-model>
</a-modal>
</template>
<script>
import AiKanCustomInput from "./modules/AiKanCustomInput";
import AiKanCustomSwitch from "./modules/AiKanCustomSwitch";
const form_fields = [
{
label: '姓名',
prop: 'name',
componentType: 'ai-kan-custom-input',
validateRule: {required: true, pattern: /^[a-zA-Z]{3,6}$/}
},
{
label: '是否删除',
prop: 'delFlag',
componentType: 'ai-kan-custom-switch',
validateRule: {required: true}
}
];
export default {
name: "AiKanFormModal",
components: {
AiKanCustomSwitch,
AiKanCustomInput
},
data() {
return {
labelCol: {
xs: { span: 24 },
sm: { span: 5 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 16 },
},
formFields: form_fields,
visible: false,
form: {},
}
},
methods: {
validateFields() {
let result = true;
for (let formItem of this.$refs.form.fields) {
this.$refs.form.validateField(formItem.prop, err => {
if (err !== "") {
result = false;
}
});
if (!result) {
break;
}
}
return result;
},
handleSubmit() {
if (this.validateFields()) {
console.log("====验证成功," + JSON.stringify(this.form));
} else {
console.log("====验证失败," + JSON.stringify(this.form));
}
},
handleCancel() {
this.visible = false;
},
}
}
</script>
效果如下图:




浙公网安备 33010602011771号