当前位置: 首页 > news >正文

父组件弹窗调用子组件时,无法通过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简单有效。

相关文章:

  • Dhtmlx Gantt教程
  • kubernetes》》k8s》》证书有效期
  • 2.第二章:政策法规与标准体系
  • c++中的enum变量 和 constexpr说明符
  • 【项目篇】仿照RabbitMQ模拟实现消息队列
  • 咖啡机语音芯片方案-WTN6040FP-14S直接驱动4欧/3W喇叭-大功率输出
  • 彻底禁用windows的语音识别快捷键win+ctrl+s
  • date-picker组件的shortcuts为什么不能配置在vue的data的return中
  • 量子混合计算革命:Qiskit 3.0开启云上量子开发新时代
  • 为什么圆形在GeoJSON中被表示为多边形(Polygon)而不是圆形类型
  • 2025职业本科网络安全课程体系设计:如何培养行业急需的实战型人才?
  • 飞帆控件:在编辑模式下额外加载的库
  • 【Amazing晶焱科技高速 CAN Bus 传输与 TVS/ESD/EOS 保护,将是车用电子的生死关键无标题】
  • 【新能源科学与技术】MATALB/Simulink小白教程(二)Buck电路【新能源电力转换与控制仿真】
  • 嵌入式WebRTC音视频实时通话EasyRTC助力打造AIOT智能硬件实时通信新生态
  • 用Python解锁链上数据的奥秘:从数据分析到可视化洞察
  • 线程封装
  • Docker镜像与容器概念解析
  • 将天气查询API封装为MCP服务
  • 【官方正版,永久免费】Adobe Camera Raw 17.2 win/Mac版本 配合Adobe22-25系列软
  • 全国铁路昨日发送2311.9万人次,同比增长11.7%创历史新高
  • AI世界的年轻人|他用影像大模型解决看病难题,“要做的研究还有很多”
  • 增诉滥用职权罪,尹锡悦遭韩国检方追加起诉
  • 深交所修订创业板指数编制方案,引入ESG负面剔除机制
  • 美乌矿产协议预计最早于今日签署
  • 智能终端出海服务创新联合体成立