如果之前定义了 属性,WebComponents 属性 setter 不会触发

WebComponents property setter not trigger if property defined before

WebComponents 属性 setter 如果 属性 之前定义,则不会触发。如下:

<foo-bar id='ele1'></foo-bar>
<foo-bar id='ele2'></foo-bar>
<script>
  ele1.foo = 'hello';

  class FooBar extends HTMLElement {

    set foo(val) {
      console.log(`set ${this.id} to ${val}`);
      this._foo = val;
    }

    get foo() {
      return this._foo
    }
  }

  customElements.define('foo-bar', FooBar);

  setTimeout(() => {
    ele1.foo = 'world';
    ele2.foo = 'world';

    console.log(`ele1.foo is ${ele1.foo}`);
    console.log(`ele2.foo is ${ele2.foo}`);
  }, 1000);
</script>

控制台输出(set ele1 to world 不是输出`):

set ele2 to world
ele1.foo is world
ele2.foo is world

所以我必须像这样观察 Object.defineProperty 的 属性:

<foo-bar id='ele1'></foo-bar>
<foo-bar id='ele2'></foo-bar>
<script>
  ele1.foo = 'hello';

  class FooBar extends HTMLElement {
    constructor() {
      super();
      this._foo = this.foo;

      Object.defineProperty(this, 'foo', {
        get: () => this._foo,
        set: val => {
          console.log(`set ${this.id} to ${val}`);
          this._foo = val;
        }
      })
    }
  }

  customElements.define('foo-bar', FooBar);

  setTimeout(() => {
    ele1.foo = 'world';
    ele2.foo = 'world';

    console.log(`ele1.foo is ${ele1.foo}`);
    console.log(`ele2.foo is ${ele2.foo}`);
  }, 1000);
</script>

<foo-bar id='ele1'></foo-bar>
<foo-bar id='ele2'></foo-bar>
<script>
  ele1.foo = 'hello';

  class FooBar extends HTMLElement {
    constructor() {
      super();
      
      this._foo = this.foo;
      delete this.foo;
    }

    set foo(val) {
      console.log(`set ${this.id} to ${val}`);
      this._foo = val;
    }

    get foo() {
      return this._foo
    }
  }

  customElements.define('foo-bar', FooBar);

  setTimeout(() => {
    ele1.foo = 'world';
    ele2.foo = 'world';

    console.log(`ele1.foo is ${ele1.foo}`);
    console.log(`ele2.foo is ${ele2.foo}`);
  }, 1000);
</script>