1.思路:
在爷组件中拿到所有孙组件的表单的 ref 然后调用表单的校验方法
2.拓展:ref的值(formRef)不止能绑定一个ref
如果多个元素的ref绑定了同一个值,那么这个值就是数组。下面可忽略,直接跳到 3.具体实现代码
正常ref只绑定一个表单
<script lang="ts" setup>
const formRef = ref<any>()// Ref
const leftTab = ref<any>({ // 表单数据
})
// 提交按钮
const save = () => {
console.log('formRef', formRef.value)
}
</script>
<template>
<div>
<ElForm label-width="120px" ref="formRef" :model="leftTab">
<el-form-item label="姓名" prop="name">
<el-input v-model="leftTab.name" size="large" />
</el-form-item>
<el-form-item label="年龄" prop="age">
<el-input-number v-model="leftTab.age" size="large" />
</el-form-item>
</ElForm>
<el-button type="primary" @click="save">确认</el-button>
</div>
</template>
当多个表单绑定同一个ref
<script lang="ts" setup>
const formRef = ref<any>()// Ref
const leftTab = ref<any>({ // 表单数据
})
// 提交按钮
const save = () => {
console.log('formRef', formRef.value)
}
</script>
<template>
<div>
<ElForm v-for="item in 4" label-width="120px" ref="formRef" :model="leftTab">
<el-form-item label="姓名" prop="name">
<el-input v-model="leftTab.name" size="large" />
</el-form-item>
<el-form-item label="年龄" prop="age">
<el-input-number v-model="leftTab.age" size="large" />
</el-form-item>
</ElForm>
<el-button type="primary" @click="save">确认</el-button>
</div>
</template>
3.具体实现代码
//爷组件
const validateAll = ref<any>([]); // 校验结果,用于在父中给予提示
const validateGrandson = ref<any>([]); // 校验的promise数组
// 传递给孙组件,用于获取所有孙组件的Ref
function pushData(data: any) {
validateGrandson.value.push(data);
}
// 提供一个方法,孙组件可以使用这个方法来触发验证
provide("validateGrandson", pushData);
//校验所有组件
async function validate() {
const arr: any = [];
validateGrandson.value.forEach((element: any) => {
arr.push(element.validate());
});
/**
* Promise.all:如果输入的任何 Promise 被拒绝,则返回的 Promise 将被拒绝(有一个失败就返回失败)
* Promise.allSettled:返回的 Promise 将被兑现,并带有描述每个 Promise 结果的对象数组。(返回所有结果包括失败的)
*/
const validateResult = await Promise.allSettled(arr);
validateAll.value = validateResult.map((item) => item.status);
}
// 提交数据
async function onSubmit() {
await validate();
// 校验通过
if (validateAll.value.every((item: any) => item === "fulfilled")) {
// 根据具体需求写通过校验后的代码……
}
}
//孙组件
const validate = inject<any>("validateGrandson"); //注入Ref
nextTick(() => {
// 表单验证方法
validate(formRef.value);
});