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>