如何让Vue在影子dom中工作

Jef*_*eff 5 javascript html5 vue.js

我有一个阴影dom,其中包含根元素和vue组件.

<template>
    <div class="container">
        <div id="app"></div>
    </div>
    <script src="http://my-site.com/app/js/vue-component.js"></script>
</template>

<div id="hostElement"></div>
<script>
// create shadow DOM on the <p> element above
const shadow = document.querySelector('#hostElement').attachShadow({mode: 'open'});
const template = document.querySelector('template');
shadow.appendChild(document.importNode(template.content, true));
</script>
Run Code Online (Sandbox Code Playgroud)

内部vue-component.js看起来像这样:

import Vue from 'vue';

const shadow = document.querySelector('#hostElement').shadowRoot;

new Vue({
    el: shadow.querySelector('#app'),
    // ...
})

// this doesn't work because I think Vue is using document.querySelector('#app')
// instead of the required document.querySelector('#hostElement').shadowRoot.querySelector('#app')
// new Vue ({
//     el: '#app'
// })
Run Code Online (Sandbox Code Playgroud)

如果我在影子dom之外使用这些东西(就像普通人一样),一切都很好.然而,似乎Vue无法处理影子dom的东西.我相信它不应该是document.querySelector在影子dom里面.相反,它应该运行shadowRoot.querySelector.

请告诉我这是否令人困惑,我处于一个不常见的用例场景中,因此有点难以解释.

Set*_*ite 8

---更新---

如果传递对元素而不是选择器的引用,则Vue将使用该元素.

let element = document.querySelector('#host-element').shadowRoot.querySelector('#your-future-vue-component');
new Vue({
  el: element,
  ...
})
Run Code Online (Sandbox Code Playgroud)

- -老东西 - -

我使用vue-custom-element为你提供了半个解决方案.我说一半,因为它将你的vue组件放入web组件中,并让你选择让它使用shadow DOM.这意味着Vue Custom元素也必须是您的shadowRoot.希望这符合您的需求.

https://github.com/karol-f/vue-custom-element

import Vue from 'vue';
import vueCustomElement from 'vue-custom-element';
import app from './app.vue';

Vue.use(vueCustomElement);
Vue.customElement("my-element", app, {shadow: true});
myShadowElement = document.createElement('my-element');
document.body.appendChild(myShadowElement);
Run Code Online (Sandbox Code Playgroud)

我认为你唯一的另一个选择是修改Vue的代码.你可以这样做并创建一个拉取请求,或者只是自己破解它.

  • @qwerty_igor我对此有些模糊,但是从https://blog.revillweb.com/open-vs-closed-shadow-dom-9f3d7427d1af开始,您似乎需要在创建阴影元素时存储参考,像这样const shadowRoot = this.attachShadow({mode:“ closed”})),然后将shadowRoot传递给vue组件中的`el`。 (2认同)
  • 使用 `{mode: "open"}` 与 `mode: "close"` 没有任何实际好处——这允许随时从 `shadowRoot` 属性引用它,例如 `anyCustomElement.shadowRoot` (2认同)