参考了懒加载的解释文档之后,我的理解如下:
元素的属性应该是分为了两种,一种外部的状态,叫做property,一种内部状态叫做attribute,外部状态的改变会触发内部状态的改变,而内部状态改变的时候会实现渲染的更新。
懒加载文章中自定义了HTML节点:<howto-checkbox>
<howto-checkbox [checked]="defaults.isChecked"></howto-checkbox>
其中[checked]应该是挂载的属性,现在还是外部状态,内部状态没有更新,即还没有更新这个属性值,当某些时刻轮到它加载的时候,会先把这个值暂存,然后删去这个外部状态,再挂载外部状态,并将这个值赋值回去。
connectedCallback() {
...
this._upgradeProperty('checked');
}
_upgradeProperty(prop) {
if (this.hasOwnProperty(prop)) {
let value = this[prop];
delete this[prop];
this[prop] = value;
}
}
在重新挂载的过程中,显示delete掉这个外部状态,再设回来,会出现一个算是监听回调的东西响应这个变化,作出相应的内部状态的改变
// When the [checked] attribute changes, set the checked property to match.
attributeChangedCallback(name, oldValue, newValue) {
if (name === 'checked')
this.checked = newValue;
}
上述attributeChangedCallback是一个属性改变的回调,但是还有另一个东西叫set,就是这个属性被设置的时候会被调用,如下
set checked(value) {
const isChecked = Boolean(value);
if (isChecked)
// OOPS! This will cause an infinite loop because it triggers the
// attributeChangedCallback() which then sets this property again.
this.setAttribute('checked', '');
else
this.removeAttribute('checked');
}
那么相当于这两个函数做了同样的事,循环调用,接下来就是将它们负责的内容分离,加一个get负责配合set的返回,而原本的attributeChangedCallback则去负责 ARIA 的状态改变。那么set、get负责状态渲染的更新、attributeChangedCallback负责交互的更新。
set checked(value) {
const isChecked = Boolean(value);
if (isChecked)
this.setAttribute('checked', '');
else
this.removeAttribute('checked');
}
get checked() {
return this.hasAttribute('checked');
}
attributeChangedCallback(name, oldValue, newValue) {
const hasValue = newValue !== null;
switch (name) {
case 'checked':
// Note the attributeChangedCallback is only handling the *side effects*
// of setting the attribute.
this.setAttribute('aria-checked', hasValue);
break;
...
}
}
以上为本人对于文档的理解,作为笔记,若有理解错误的地方,还请大家指出!谢谢!
参考资料:
https://blog.csdn.net/qihoo_tech/article/details/101044977
https://web.dev/custom-elements-best-practices/#make-properties-lazy
https://blog.csdn.net/weixin_47075145/article/details/125922617