【发布时间】:2020-01-17 17:10:17
【问题描述】:
背景
通常,在 Vue.js 组件中使用模态框时,通常会创建一个可重用的modal 组件,然后使用来自子组件的事件来控制该组件的状态。
例如,考虑以下代码:
App.vue
<div id="app">
<!-- Main Application content here... -->
<!-- Place any modal components here... -->
<modal ref="ContactForm"></modal>
</div>
ChildComponent.Vue
要从子组件打开模式,我们只需触发以下事件:
bus.$emit('open-modal', 'ContactForm');
注意 1:bus 是一个单独的 Vue 实例,它允许在所有组件之间触发事件,而不管它们的关系如何。
注意 2:我故意省略了我的 modal 组件代码,因为它与问题无关。
问题
虽然上述工作绝对正常,但有一个关键问题......
为了将modal 添加到我的应用程序中,而不是将modal 组件放在引用它的子组件中,我必须将all 模态框放在App.vue 中,如下所示确保它们在 DOM 树中尽可能高(以确保它们出现在所有内容之上)。
因此,我的App.vue 有可能最终变成这样:
<div id="app">
<!-- Main Application content here... -->
<!-- Place any modal components here... -->
<modal ref="SomeModal1"></modal>
<modal ref="SomeModal2"></modal>
<modal ref="SomeModal3"></modal>
<modal ref="SomeModal4"></modal>
<modal ref="SomeModal5"></modal>
<modal ref="SomeModal6"></modal>
<modal ref="SomeModal7"></modal>
</div>
如果能够将modal 组件放置在子组件的DOM 中会更简洁。
但是,为了确保模态显示在 DOM 中的所有内容之上(特别是带有集合 z-index 的项目),我看不到上述内容的替代方案...
任何人都可以提出一种方法来确保我的模式能够正常工作,即使它们被放置在子组件中?
潜在解决方案
我确实考虑过以下解决方案,但它似乎很脏......
- 触发
open-modal事件 - 将相关的
modal组件移动到父App.vue组件 - 显示模态
附加信息
如果上述内容不明确,我会尽量避免在我的 App.vue 组件中定义 all 模态,并允许在任何子组件中定义我的模态。
目前我无法做到这一点的原因是,模态框的 HTML 必须在 DOM 树中尽可能高地出现,以确保它们出现在所有内容之上。
【问题讨论】:
-
正如您所说的,“规范”是重用。例如,您只有一个模态实例,并且在打开它时动态注入内容。事实上,今天的规范是没有任何模态实例,并在需要时以编程方式创建一个,并在将回调响应传递给其触发组件后将其销毁。如果你最终得到了一堆模态实例,那么你就没有重用。你在硬编码。
-
@AndreiGheorghiu - 我措辞不好,你解释它的方式正是我的模态组件的工作方式。由于每个
modal都是有条件地呈现的,它们不会同时出现在DOM 中。 -
在这种情况下,您只需将
<body>设置为模态实例的目标元素,当您追加它时。这就是避免任何z-index问题的方法。 -
@AndreiGheorghiu - 等等,我有点困惑。
target元素是什么意思?modal不是由我的 JS 创建的,它是由 Vue.js 有条件地呈现的吗 -
您有没有
.modal { z-index: 2000;}不起作用的用例?对于现代浏览器,z-index 的理论最大值约为 20 亿。所以我不再担心它在 DOM 中的位置,而是在有意义的地方添加组件。
标签: javascript css vue.js modal-dialog