在 iframe 内的 Vue 3 实例中延迟注册事件侦听器

Delayed registration of event listeners in a Vue 3 instance inside an iframe

出于一个非常具体的原因*,我需要一个 Vue 实例到 运行 在 iframe 中。我设法在 this thread on Vue forum 之后做到了这一点,并调整了代码以支持 Vue 3 并删除了插槽,因为我只需要在 iframe.[=18= 中 运行 的特定组件]

但是有一个非常具体的问题,我什至没有设法开始调试。

从这个minimal reproducible example on CodeSandbox中可以看出,当一个新元素被添加到iframe中时,需要花费相当多的时间用户事件(即点击)开始获得认可。 (在我的场景中更加明显,完全无法使用)

精通 Vue 的人是否至少了解为什么会发生这种情况以及是否有办法防止这种情况发生?

如有任何见解,我们将不胜感激。谢谢。


*原因是我正在构建一个将侧边栏注入页面的浏览器扩展,我需要隔离 CSS,因为扩展要在各种页面上使用,所以它几乎不可能阻止所有的stlyes泄漏到注入的侧边栏中。

是的,避免使用 iframe 并使用 #myDiv{ all: unset } 在某种程度上起作用,但对于页面 CSS 中定义的某些非常具体的选择器会失败(并且完全不适用于input 个元素)。在我想要支持的所有页面上寻找它们很快就会变成一场噩梦。

回答我自己的问题,因为没有人对此有任何说明。然而,这并不能回答最初的问题,但我认为如果有人偶然发现了这个问题,他们应该知道我是如何解决它的。

最后,我放弃了 iFrame 的想法,并使用 Shadow DOM 的概念将页面的 CSS 和注入的扩展程序的 CSS 相互隔离。

尽管这种方法有其自身的注意事项*,但恕我直言,它优于使用 iframe。

*比如需要手动将自定义样式注入影子根。并且还需要将 shadow-root 元素存储在应用程序的所有部分都可以访问的某个位置(不是 Vuex,元素本身不能存储在那里)以使事情正常进行。

这是我用来将边栏插入页面的代码片段:

// append a new node to the document body
let shadowHost = document.createElement("div");
document.body.appendChild(shadowHost);
    
// make it the root of our shadow DOM
let shadow = shadowHost.attachShadow({ mode: 'open'})

// create a new node for the sidebar
let sidebar = document.createElement("div");
sidebar.id = "my-sidebar";

// and also a style node into which we put all our custom css
const style = document.createElement('style');
// getPackedCss is my function that returns all the custom css as a string
style.textContent = getPackedCss();

// and append those to the shadow DOM
shadow.appendChild(style);
shadow.appendChild(sidebar);
    
// store the shadow root somewhere that we can access
// globally in order to select elements from it
staticStore.shadowRoot = shadow;

// create our vue app and mount it to the shadow DOM
const app = createApp(MyApp);
app.mount(sidebar);

如果你确实需要 Vue 3 和 iframe 来互相喜欢,我想你只能靠自己了。