需求是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,否则返回 falsereturn 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>