如何解耦 Web 组件?

mcv*_*mcv 5 javascript loose-coupling web-component custom-element

我正在尝试使用纯 javascript Web 组件进行无框架工作。我希望我的 Web 组件能够独立工作并在不同的站点上使用,但我也希望两个组件能够进行通信。因此它们应该能够在不紧密耦合的情况下进行通信。

当我使用 Angular 时,这很容易。我可以通过 HTML 属性将对象传递给组件,并且组件将其作为对象而不是字符串接收。但在纯 JavaScript 中,属性始终是字符串。传递对象或以其他方式使 Web 组件相互了解并能够进行通信的正确方法是什么?

Sup*_*arp 6

使用 Web 组件,您可以像您所说的那样通过属性传递对象,但也可以通过方法或属性(实际上是 setter 方法)传递对象。

<my-component id="comp1"></my-component>
...
var myObject = { y:1, y:2 }
comp1.value = myObject     //via property
comp1.setValue( myObject ) //via method
Run Code Online (Sandbox Code Playgroud)


Int*_*lia 4

这是一个包含两个本机 V1 Web 组件的示例应用程序。<component-1>可以交谈,<component-2>因为您向 中提供了一个 ID <component-1>,并且该 ID 指的是 上设置的 ID <component-2>

这类似于<label>标签与其for属性的工作方式。

超文本标记语言

<component-1 link-id="c2"></component-1>
<hr/>
<component-2 id="c2"></component-2>
Run Code Online (Sandbox Code Playgroud)

JS

// Class for `<component-1>`
class Component1 extends HTMLElement {
  constructor() {
    super();
    this._linkedComponent = null;
    this._input = document.createElement('input');
    this._input.addEventListener('focus', this._focusHandler.bind(this));

    this._button = document.createElement('button');
    this._button.textContent = 'Add';
    this._button.addEventListener('click', this._clickHandler.bind(this));
  }

  connectedCallback() {
    this.appendChild(this._input);
    this.appendChild(this._button);
  }

  static get observedAttributes() {
    return ['link-id'];
  }

  attributeChangedCallback(attrName, oldVal, newVal) {
    if (oldVal !== newVal) {
      if (newVal === null) {
        this._linkedComponent = null;
      }
      else {
        this._linkedComponent = document.getElementById(newVal);
      }
    }
  }

  _clickHandler() {
    if (this._linkedComponent) {
      this._linkedComponent.value = this._input.value;
    }
  }

  _focusHandler() {
    this._input.value = '';
  }
}

// Class for `<component-2>`
class Component2 extends HTMLElement {
  constructor() {
    super();
    this._textArea = document.createElement('textarea');
    this._textArea.setAttribute('style','width:100%;height:200px;');
  }

  connectedCallback() {
    this.appendChild(this._textArea);
  }

  set value(newValue) {
    this._textArea.value += (newValue+'\n');
  }
}

customElements.define('component-1', Component1);
customElements.define('component-2', Component2);
Run Code Online (Sandbox Code Playgroud)

<component-1>仅当存在具有通过其属性<component-2>提供的 ID 的组件时才会进行对话。<component-1>link-id