【问题标题】:How to define global constant when creating Web component?创建 Web 组件时如何定义全局常量?
【发布时间】:2021-05-14 15:05:39
【问题描述】:

我正在创建自定义 Web 组件“upload-widget”,并在构造函数中声明三个常量,以便稍后在函数中引用:

const template = document.createElement('template');
template.innerHTML = `
  <div id="dropper-zone">
    <input type="file" name="file_input" id="file_name">
    <button type="button" id="upload_btn">Upload</button>
    <div id="upload_status"></div>
  </div>
  `;

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

    const FILE_NAME = this.shadowRoot.getElementById("file_name");
    const UPLOAD_BUTTON = this.shadowRoot.getElementById("upload_btn");
    const UPLOAD_STATUS = this.shadowRoot.getElementById("upload_status");


  };

  upload_action() {
    if (!FILE_NAME.value) {
    console.log("File does not exists");
        return;
    UPLOAD_STATUS.innerHTML = 'File Uploaded';
  };

  connectedCallback() {
    UPLOAD_BUTTON.addEventListener("click", () => this.upload_action());
  }
}

customElements.define('upload-widget', UploadWidget);

此代码失败,因为 Javascript 无法识别“connectedCallback()”和函数“upload_action()”中声明的常量。将声明移动到任一函数使常量仅对函数范围有效,而不是超出范围。 如何声明对类的整个范围(包括函数)有效的常量/变量?

【问题讨论】:

  • let/const/var 声明的变量 始终只能在声明它们的范围内访问(在本例中为constructor 函数) . 不,您不希望它们成为全局常量,您希望UploadWidget 的每个实例都有不同的值。所以让它们成为你实例的对象属性。

标签: javascript class scope declaration web-component


【解决方案1】:

您需要将它们声明为类变量,因此您的 constructor 看起来像:

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

    this.FILE_NAME = this.shadowRoot.getElementById("file_name");
    this.UPLOAD_BUTTON = this.shadowRoot.getElementById("upload_btn");
    this.UPLOAD_STATUS = this.shadowRoot.getElementById("upload_status");
  };

稍后在代码中,您可以通过this.UPLOAD_BUTTON 访问它们。

建议:命名变量时尽量使用驼峰式,看起来更“javascripty”。所以不要写this.UPLOAD_BUTTON,而是写this.uploadButton

【讨论】:

    【解决方案2】:

    注意你的模板使用有点臃肿,你可以这样做:

     constructor() {
        let html = `
             <div id="dropper-zone">
               <input type="file" name="file_input" id="file_name">
               <button type="button" id="upload_btn">Upload</button>
               <div id="upload_status"></div>
             </div>`;
        super() // sets AND returns this scope
          .attachShadow({mode: 'open'}) // sets AND returns this.shadowRoot
          .innerHTML = html;
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多