【问题标题】:ES6 Custom Elements InheritanceES6 自定义元素继承
【发布时间】:2019-05-05 17:31:44
【问题描述】:

我正在尝试在自定义元素中使用继承。

这是我的页面

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8" />
  <title></title>
</head>

<body>
  <base-element></base-element>
  <language-drop-down></language-drop-down>

  <script type="module" src="./custom-elements/BaseHTMLElement.js"></script>
  <script type="module" src="./custom-elements/language-drop-down/js/LanguageDropDown.js"></script>
</body>

</html>

基本自定义元素

    export default class BaseHTMLElement extends HTMLElement {

    get currentDocument() { return document.currentScript.ownerDocument };

    constructor(params) {
        super();

        this.params = params;

        this.attachShadow({ mode: 'open' });
        debugger

        // Select the template and clone it. Finally attach the cloned node to the shadowDOM's root.
        // Current document needs to be defined to get DOM access to imported HTML
        if(this.params && this.params.templateName){
            this.template = this.currentDocument.querySelector(this.params.templateName);
            this.instance = this.template.content.cloneNode(true);

            this.shadowRoot.appendChild(this.instance);
        }else{
            let div = document.createElement("DIV");
            div.innerHTML = "element without template";
            this.shadowRoot.appendChild(div);
        }
    }
    connectedCallback() {
        this.loadLocalStrings();
    }
    childrenChangedCallback() {

    }
    disconnectedCallback() {

    }
    attributeChangedCallback(attrName, oldVal, newVal) {

    }

    loadLocalStrings() {

    }
   }

   window.customElements.define('base-element', BaseHTMLElement);

以及语言下拉自定义元素

import * as BaseHTMLElement from '../../BaseHTMLElement.js';

class LanguageDropDown extends BaseHTMLElement {

    constructor() {
        super({
            templateName: '#language-drop-down-template'
        });  
    }
    connectedCallback() {

        let dropdown = this.shadowRoot.querySelectorAll('.dropdown');        
        $(dropdown).dropdown();
    }
    childrenChangedCallback() {

    }
    disconnectedCallback() {

    }
    attributeChangedCallback(attrName, oldVal, newVal) {

    }
};

window.customElements.define('language-drop-down', LanguageDropDown);

及其模板部分

<template id="language-drop-down-template">
    <link href="./custom-elements/language-drop-down/css/languageDropDown.css" rel="stylesheet" />

    <div class="dropdown">
        <button class="btn dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
            Dropdown button
        </button>
        <div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
            <a class="dropdown-item" href="#">Action</a>
            <a class="dropdown-item" href="#">Another action</a>
            <a class="dropdown-item" href="#">Something else here</a>
        </div>
    </div>
</template>

<script type="module" src="../BaseHTMLElement.mjs"></script>
<script type="module" src="./js/languageDropDown.mjs"></script>

现在,在 chrome 最新版本中,它应该可以在不编译/使用 polyfill 的情况下工作,对吧? 我的问题是控制台中的这条消息

Uncaught TypeError: Class extends value [object Module] is not a constructor or null

我不明白我错在哪里......有人有想法吗?

所有这些都是因为我想避免使用 HTML 导入,因为它已被弃用并将在 M73 中删除。

如果我使用

<script src="./custom-elements/BaseHTMLElement.js"></script>
<link rel="import" href="./custom-elements/language-drop-down/LanguageDropDown.html">

然后删除 导出默认 BaseHTMLElement ... 从 '../../BaseHTMLElement.js' 导入 * as BaseHTMLElement;

效果很好!

【问题讨论】:

    标签: javascript ecmascript-6 es6-modules custom-element


    【解决方案1】:

    我发现使用

    import BaseHTMLElement from '../../BaseHTMLElement.js';
    

    让它工作

    【讨论】:

      【解决方案2】:

      你的线路

      import * as BaseHTMLElement from '../../BaseHTMLElement.js';
      

      错了。该脚本将类导出为其默认导出。您在此处将 all 导出作为模块命名空间对象导入 - 当尝试像 class extends 子句中的类一样使用它时,您会得到“[object Module] is not a constructor or null”。

      你应该使用

      import {default as BaseHTMLElement} from '../../BaseHTMLElement.js';
      

      import BaseHTMLElement from '../../BaseHTMLElement.js';
      

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多