【问题标题】:Inheritance of web component in js filesjs文件中web组件的继承
【发布时间】:2017-09-14 12:39:27
【问题描述】:

第一个组件:x-input。一个什么都不做的非常简单的输入组件:

(function() {
    class XInput extends HTMLElement {
        static get template() {
            const template = document.createElement('template');
            template.innerHTML = `
                <style>
                    :host {
                        display: block;
                    }
                </style>

                <input id="input">
            `;
            return template;
        }

        constructor() {
            super();
            this.attachShadow({mode: 'open'});
            this.shadowRoot.appendChild(XInput.template.content.cloneNode(true));
        }
    }

    window.customElements.define('x-input', XInput);
})();

我的组件在一个 .js 文件中,所以我不需要在我的客户端页面中使用 HTML 导入。 现在,我需要第二个从 x-input 继承的 Web 组件:

(function() {
    class XInputNumber extends XInput {

    }

    window.customElements.define('x-input-number', XInputNumber);
})();

如果我尝试在页面中使用第二个元素 -> Uncaught ReferenceError: XInput is not defined.

<html>
    <head>
        <script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
        <script src="/bower_components/shadydom/shadydom.min.js"></script>

        <script src="/webcomponents/input/x-input.js"></script>
        <script src="/webcomponents/input/x-input-number.js"></script>
    </head>
    <body>
        <p><x-input></x-input></p>
        <p><x-input-number></x-input-number></p>
    </body>
</html>

如果我在 html 文件中编写我的 web 组件,没问题,但我必须使用 HTML 导入(我尝试不使用它)。

我怎样才能做到这一点?

【问题讨论】:

  • JS 类仅在当前上下文范围内可见。也许this question 会有所帮助。另请查看export
  • 确实,我的对象进入了 IIFE。如果我删除这个 IIFE,我的例子就有效。但它只有效,因为我在标题中声明了我的两个 Web 组件。如果我只想在我的页面中使用第二个 Web 组件(所以我只声明了这个),它不会工作(依赖的 XInput 没有在任何地方声明......
  • 我不确定你是否注意到我提到的export。目前尚不清楚您的平台要求是什么。您可能可以使用export default class 测试您的代码。一些最新版本的浏览器应该支持它。
  • 我的平台要求是IE11+,所以什么都用不了……

标签: javascript inheritance web-component custom-element


【解决方案1】:

如您所见,XInput 类仅在闭包中定义。如果你想在其他地方重用它,你可以全局定义它,或者在 customElements.get() 方法的帮助下检索它。

x-input-number.js 文件中:

(function() {
    var XInput = customeElements.get('x-input');

    class XInputNumber extends XInput {

    }

    window.customElements.define('x-input-number', XInputNumber);
})();

或直接:

class XInputNumber extends customeElements.get('x-input') {}

【讨论】:

  • 很好,谢谢。但是我必须将 x-input.js 文件贴到我的页面中。有没有可能避免这种情况?
  • 我不明白。你怎么能使用 x-input 而不事先声明呢?
  • 如果在一个页面中,我只使用 x-input-number,我不想声明 x-input。我只想声明 x-input-number。如果没有。使用这些 Web 组件的开发者必须知道所有 Web 组件的继承方案。
  • 如果尚未声明,则应从 x-input-number 导入 JS 文件。使用 ES6 导入/导出(尚未在所有浏览器中原生实现)或动态添加
  • 我会尝试动态添加一个
【解决方案2】:
export default class ChildComponent extends ParentComponent {
  constructor() {
    super("child template");
  }

  connectedCallback() {
    super.connectedCallback();
  }
}

customElements.define('x-child', ChildComponent);

父组件:

export default class ParentComponent {
  constructor(childTemplate) {
    this.appendChild('foo<div class="refChildContent"></div>bar');
    this.childTemplate = childTemplate;
  }

  connectedCallback() {
    this.querySelector('.refChildContent').innerHTML = this.childTemplate;
  }
}

customElements.define('x-parent', ParentComponent);

结果:

<x-child>
 foo
 <div class="refChildContent">
    child html
 </div>
 bar
</x-child>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-30
    • 2021-07-13
    • 2013-12-26
    • 1970-01-01
    • 2019-06-30
    • 2010-11-10
    • 2017-03-12
    • 2019-07-02
    相关资源
    最近更新 更多