需求是VUE2框架用elementUI写复杂表单组件,比如,3个相同功能的表单共用一个提交按钮,把相同功能的表单写成一个子组件,另一个父组件包含子组件的重复调用和一个提交按钮,并且要求提交时校验必填项。
注意:
1.validate函数不传参数就会返回一个promise
2.子组件中写了this.$refs.form?.map...是因为真实项目中el-form是进行了循环的,这里可以自定义修改
3.父组件中要用promise来处理调用子组件的方法
子组件:
<template>
<el-form ref="form" :model="formData" :rules="formRules" label-width="120px">
<el-form-item label="姓名" prop="name">
<el-input v-model="formData.name"></el-input>
</el-form-item>
<el-form-item label="邮箱" prop="email">
<el-input v-model="formData.email"></el-input>
</el-form-item>
<!-- 其他表单项 -->
</el-form>
</template>
<script>
export default {
data() {
return {
formData: {
name: '',
email: ''
// 其他表单项
},
formRules: {
name: [
{ required: true, message: '请输入姓名', trigger: 'blur' }
],
email: [
{ required: true, message: '请输入邮箱', trigger: 'blur' }
]
// 其他表单项的校验规则
}
};
},
methods: {
validateForm() {
const validatePromises = this.$refs.form?.map(v => {
return v.validate();
});
if (validatePromises) {
return Promise.all(validatePromises)
.then(results => {
// 检查结果数组,如果所有项都是 true,则返回 true,否则返回 false
return results.every(result => result);
})
.catch(() => {
// 如果有任何验证 Promise 失败,则捕获错误
return false;
});
} else {
// 如果 this.$refs.form 不存在,直接返回 false 或抛出错误
return false;
}
}
}
};
</script>
父组件
<template>
<div>
<FormComponent v-for="(ref,index) in formRefs" :key="index" :ref="ref">
</FormComponent>
<el-button type="primary" @click="submitForms">提交</el-button>
</div>
</template>
<script>
import FormComponent from './FormComponent.vue';
export default {
data() {
return {
formRefs: []
};
},
components: {
FormComponent
},
mounted() {
// 根据需要调用表单的次数,此处假设为10次
for (let i = 0; i < 10; i++) {
this.formRefs.push(`form${i + 1}`);
}
},
methods: {
async onSubmit() {
// 1、pc端:一次性校验所有题
Promise.all(
this.formRefs?.map(v => {
return this.$refs?.[v]?.[0]?.validateForm();
})
)
.then(res => {
if (res?.every(v => v)) {
const formDataList = this.formRefs?.map(v => {
return this.$refs?.[v]?.[0]?.form;
});
// 2、提交问卷
console.log('formDataList', formDataList);
} else {
// 找出所有校验不通过的表单
const falseFormList = res.filter(v => !v);
// TODO 自定义操作
}
})
.catch(() => {
this.$alert('请稍后重试', '提示', {
dangerouslyUseHTMLString: true
});
});
}
}
};
</script>