如果之前定义了属性,则WebComponents属性设置器不会触发



WebComponents属性设置器如果之前定义了属性,则不会触发。如下:

<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>

最新更新