父组件中同名emit事件是否会叠加触发,导致多个弹窗同时关闭?
问题修复方案
根因定位
问题核心来自两个方面:
- 显隐变量混用:每个弹窗都定义了两个无关联的显隐变量,状态更新完全不同步:
- Modal1的
ModalWrapper的isVisible属性绑定modal1IsVisible,但@close事件修改的是modal1Open,而内部CModal1的v-if和自身@close事件又使用modal1IsVisible,两个变量未做同步的情况下逻辑完全混乱 - Modal2的
ModalWrapper的isVisible属性绑定modal2Open,但内部CModal2的v-if和自身@close事件使用modal2IsVisible,打开Modal2的事件也只修改了modal2Open,modal2IsVisible从未被置为true,本身就存在逻辑错误
- Modal1的
- 事件冒泡/点击穿透:如果
ModalWrapper的遮罩层为全屏fixed定位,即使给Modal2加了z-30,如果上层遮罩的点击事件未阻止冒泡,也可能出现点击上层触发下层事件的情况。
修复步骤
- 统一每个弹窗的显隐变量,每个弹窗仅保留一个控制变量,所有属性绑定和状态修改都复用同一个变量:
<template> <!-- Modal1 统一使用 modal1Visible 控制显隐 --> <ModalWrapper @close="modal1Visible = false" :isVisible="modal1Visible" > <CModal1 v-if="modal1Visible" :formData="formData" @close="modal1Visible = false" @save-data="(val) => saveData(val)" @open-modal-2-clicked="modal2Visible = true" /> </ModalWrapper> <!-- Modal2 统一使用 modal2Visible 控制显隐 --> <ModalWrapper @close="modal2Visible = false" :isVisible="modal2Visible" class="z-30" > <CModal2 v-if="modal2Visible" @close="modal2Visible = false" /> </ModalWrapper> </template>
- 在
ModalWrapper组件内部,给遮罩层、右上角关闭按钮的点击事件添加.stop修饰符阻止事件冒泡,避免点击上层弹窗触发下层的关闭事件。 - 确认所有
ModalWrapper的z-index层级,下层弹窗的层级必须低于上层弹窗的z-30,避免出现点击穿透。
关于是否将ModalWrapper移入子组件内部
非常推荐该方案:
- 避免父组件重复编写
ModalWrapper的重复逻辑,减少样板代码 - 每个弹窗的过渡效果、关闭逻辑、显隐控制都封装在组件内部,父组件仅需要传递
visible属性和监听close事件即可,大幅降低父组件状态管理的复杂度,从根源上避免变量混用的问题。
内容的提问来源于stack exchange,提问作者LovelyAndy
相关产品推荐
相关产品推荐

