使属性懒惰

web*_*ter 0 javascript web-component custom-element

我读的最佳做法的文章在这里。我遇到了以下几行:

在加载定义之前,开发人员可能会尝试在元素上设置属性。如果开发人员使用一个框架来处理加载组件、将它们插入到页面中并将它们的属性绑定到模型,则尤其如此。

解决此问题的建议解决方案是:

_upgradeProperty(prop) {
  if (this.hasOwnProperty(prop)) {
    let value = this[prop];
    delete this[prop];
    this[prop] = value;
  }
}
Run Code Online (Sandbox Code Playgroud)

我一直在尝试了解会发生这种情况的场景,并尝试了解这段代码如何解决这个问题。我试图找到任何参考资料,但无法找到任何类似的东西。

请有人解释这种情况以及我们在这里试图解决什么问题。

eik*_*iko 5

在您调用之前,Web 组件不会完全初始化您的元素customElements.define('custom-tag', CustomElement);然而,一旦页面呈现,任何<custom-tag>存在于 DOM 中HTMLUnknownElement。因此,在页面呈现和您调用 之间的时间段内,customElements.define(...)有人可能会调用以下内容:

document.querySelector('custom-tag').someProperty = someValue
Run Code Online (Sandbox Code Playgroud)

这将修改尚未初始化的CustomElement.

为什么会发生这种情况?

我认为这很可能是将 Web Components 与前端框架(Angular、Vue 等)一起使用的副作用。这些框架通常具有在渲染之后发生的初始化代码,并且可能存在用户可能没有足够的控制来阻止框架在 Web 组件之前初始化的情况。

代码片段如何解决问题?

fragment 函数_upgradeProperty()旨在在 中调用connectedCallback(),在 Web 组件完全定义并附加到现有元素之后调用。如果您的班级中有任何自定义设置器,例如:

class CustomElement {
  set someProperty(value) {
    this._someProperty = value.toLowerCase();
  }
}
Run Code Online (Sandbox Code Playgroud)

那么有可能在 setter 存在之前设置属性,这意味着原始值被直接保存到实例的someProperty属性中,而不是被转换为小写并保存到_someProperty. 在定义 setter 之后删除属性并重新分配它可以确保正确处理该值(在这种情况下,将其设为小写并保存在正确的位置)。