javascript 如何在Web组件中使用Web组件?

vu8f3i0k  于 2023-03-28  发布在  Java
关注(0)|答案(2)|浏览(142)

我试图弄清楚如何在另一个Web组件中使用一个Web组件(两者都继承自同一个基类)。
问题似乎出在我创建shadow dom的方式上:

import BaseElement from "./base.js";

class PopupHeader extends BaseElement {
  constructor() {
    super();
  }

  async render(initial = false) {
    this.shadowRoot.innerHTML = `
        <header>
          <a href="https://example.com" id="logo" target="_blank"><img src="assets/logo.svg" alt="logo" /></a>
        </header>
      `;
  }

  async connectedCallback() {
    await this.render(true);
  }
}

customElements.define("popup-header", PopupHeader);

export default PopupHeader;

和base.js:

export default class BaseElement extends HTMLElement {
  constructor() {
    super();
    
    this.attachShadow({ mode: "open" });
  }

main-app.js

import BaseElement from "./base.js";

class EasyApplier extends BaseElement {
  constructor() {
    super();

    this.render = this.render.bind(this);
  }

  async render(initial = false) {
    this.shadowRoot.innerHTML = `
        <div id="${this.ns}">
          <popup-header></popup-header>
          Import profiles: <input type="file" id="json-file-input" accept="application/json" />
        </div>
      `;

  }
...
}

问题是只显示标题,而不是主要组件的其余部分。
我怀疑这与此有关。shadowRoot被覆盖,有没有办法避免这种情况?

pw9qyyiw

pw9qyyiw1#

快速浏览一下:${this.ns}??您在constructing阶段调用此操作??
难道不能简化为:

class BaseElement extends HTMLElement {
  constructor( html ) {
    super().attachShadow({ mode: "open" }).innerHTML = html;
  }
}

customElements.define("popup-header", class extends BaseElement {
  constructor() {
    super(`<header>POPUP-HEADER</header>`);
  }
});

customElements.define("main-header", class extends BaseElement {
  constructor() {
    super(`<h1>MAIN-HEADER</h1><popup-header></popup-header>`);
  }
});
<main-header></main-header>
clj7thdc

clj7thdc2#

我为你简化了你的代码。不知道为什么你认为你需要异步渲染,或者为什么你发送了你没有使用的参数。
已将调用render()connectedCallback()移动到BaseElement中。
注意,Stackoverflow上的代码片段不需要导出,因为它们都在同一个文件中。如果每个元素都在自己的单独文件中,你仍然需要它们,但我建议只使用export class SomeElement extends AnotherElement,而不是在单行上导出。
问题可能是您试图从相对路径from "./base.js"而不是绝对路径from "/base.js"(无点)导入。

class BaseElement extends HTMLElement {
  constructor() {
    super();
    
    this.attachShadow({ mode: "open" });
  }
  
  connectedCallback() {
    this.render();
  }
}

// =======================

// import BaseElement from "/base.js"; // from the root

class PopupHeader extends BaseElement {
  render() {
    this.shadowRoot.innerHTML = `
        <header>
          <a href="https://example.com" id="logo" target="_blank"><img src="assets/logo.svg" alt="logo" /></a>
        </header>
      `;
  }
}

customElements.define("popup-header", PopupHeader);

// =======================

// import BaseElement from "/base.js";                    // from root
// import PopupHeader from "/SUBFOLDER/popup-header.js";  // from root/SUBFOLDER

class EasyApplier extends BaseElement {
  render() {
    this.shadowRoot.innerHTML = `
        <div id="${this.ns}">
          <popup-header></popup-header>
          Import profiles: <input type="file" id="json-file-input" accept="application/json" />
        </div>
      `;

  }
}

customElements.define("easy-applier", EasyApplier);
<easy-applier></easy-applier>

相关问题