首页 > 解决方案 > 如果之前定义了属性,则不会触发 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>

标签: propertiesweb-componentsetter

解决方案


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


推荐阅读