欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 养生 > 父组件弹窗调用子组件时,无法通过ref、provide、inject等方法调用子组件的方法

父组件弹窗调用子组件时,无法通过ref、provide、inject等方法调用子组件的方法

2025/4/28 2:14:36 来源:https://blog.csdn.net/weixin_48420104/article/details/147457339  浏览:    关键词:父组件弹窗调用子组件时,无法通过ref、provide、inject等方法调用子组件的方法

问题:

父组件弹窗调用子组件时,无法通过ref、provide、inject等方法调用子组件的方法

场景:

<!-- 新增/编辑弹窗 -->
<el-dialog style="width: auto;" v-model="dataSourceVisible" :title="$t(isEdit ? 'dataSource.editDataSource' : 'dataSource.addDataSource')" @close="handleClose"><component :is="DataSource" ref="dataSourceRef" :OBJECT_GUID="OBJECT_GUID" :PARENT_PATH="PARENT_PATH" @close="handleClose" :showPerformance="showPerformanceList" />
</el-dialog>

需求是在点击弹窗右上角的关闭按钮时,需要清空组件里面的表单验证。但是无法通过ref、provide、inject等方法调用子组件的方法。

失败分析:

父组件无法通过ref等方式调用子组件的方法,主要原因包括子组件尚未创建完成、子组件方法未声明、父组件调用时机不正确等‌。弹窗里面的子组件内容确实是动态渲染的组件,有可能即使父组件弹窗出来了,弹窗内容还没渲染出来,从而导致父子组件无法通信。

解决方法:

方法1:

子组件对外暴露方法clearDialogValidate,父组件通过ref调用子组件clearDialogValidate方法(不推荐

defineExpose({clearDialogValidate
});

不是说不能通过ref调用子组件实例吗?但是,

使用 v-if 来控制子组件的渲染,确保在调用方法时子组件已经挂载;然后使用 nextTicksetTimeout 来延迟调用子组件的方法,确保子组件已经挂载。

<!-- 新增/编辑弹窗 -->
<el-dialog style="width: auto;" v-model="dataSourceVisible" :title="$t(isEdit ? 'dataSource.editDataSource' : 'dataSource.addDataSource')" @close="handleClose"><component :is="DataSource" v-if="dataSourceVisible" v-model="dataSourceVisible" ref="dataSourceRef" :OBJECT_GUID="OBJECT_GUID" :PARENT_PATH="PARENT_PATH" @close="handleClose" :showPerformance="showPerformanceList" />
</el-dialog>
const dataSourceRef = ref(null);
// 关闭新增/编辑数据弹窗
const handleClose = () => {setTimeout(() => {if (dataSourceRef?.value?.componentRef?.value &&typeof dataSourceRef.value.componentRef.value.clearDialogValidate === 'function') {dataSourceRef.value.componentRef.value.clearDialogValidate();}}, 0); // 延迟 100ms 或 0 ms都可以,给子组件足够的时间挂载OBJECT_GUID.value = '';requestDataSource();showPerformanceList.value = false;dataSourceVisible.value = false;
}

这样就可以点击右上角关闭按钮时调用子组件的clearDialogValidate去清空校验了。但是会使组件内的clearValidate方法报错。所以行不通。

// 清空表单校验
const clearDialogValidate = () => {setTimeout(() => {proxy.$refs["dataSourceRuleForm"].clearValidate();}, 0);
};

方法2:

 父组件弹窗关闭时销毁子组件(调用官方API:destroy-on-close),然后子组件在挂载成功时,清空一下表单校验即可。

在el-dialog里写上destroy-on-close (在关闭弹窗时销毁子组件内容)

<!-- 新增/编辑数据链接弹窗 -->
<el-dialog style="width: auto;" v-model="dataSourceVisible" :title="$t(isEdit ? 'dataSource.editDataSource' : 'dataSource.addDataSource')" @close="handleClose" destroy-on-close><component :is="DataSource" :OBJECT_GUID="OBJECT_GUID" :PARENT_PATH="PARENT_PATH" @close="handleClose" :showPerformance="showPerformanceList" />
</el-dialog>

子组件:

在子组件onMounted挂载时调用clearDialogValidate();清空一下校验即可。

onMounted(() => {showPerformanceList.value = props.showPerformance......clearDialogValidate();
});
// 清空表单校验
const clearDialogValidate = () => {setTimeout(() => {proxy.$refs["dataSourceRuleForm"].clearValidate();}, 0);
};

 总结:

方法2简单有效。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词