当前位置: 首页 > 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系列软
  • 杨靖︱“一笔糊涂账”:博马舍与美国革命
  • 金湘军辞去山西省省长职务
  • 上海市统计局:经济运行开局平稳,高质量发展扎实推进
  • 巴基斯坦航天员选拔工作正在进行,1人将以载荷专家身份参加联合飞行
  • 一季度提高两只医药基金股票仓位,中欧基金葛兰加仓科伦药业、百利天恒
  • 印尼塔劳群岛发生6.2级地震,震源深度140千米