如何反映属性但不触发元素重新渲染?

时间:2019-11-27 15:13:17

标签: web-component lit-element

我正在将自定义元素下拉列表转换为lit-element。现有元素显示下拉选项的方式是通过在元素上设置expanded布尔属性,然后通过CSS显示/隐藏选项:

my-element:not([expanded]) .options-container {
  display: none;
}

my-element[expanded] .options-container {
  display: block;
}

该组件不需要重新渲染,因为逻辑全在CSS中。

如何使用lit-element实现此行为,而不重新渲染组件?如果有很多下拉选项,则渲染成本很高。

我尝试实现一个shouldUpdate,如果仅更改expanded,则返回false-但这会导致通过属性设置时,照明元素不会将expanded反映到该属性为了通过CSS显示/隐藏,是必需的。

这是我所拥有的,不起作用:

class MyDropdown extends LitElement {
  static get properties() {
    return {
      expanded: { type: Boolean, reflect: true },
      ...
    };
  }

  shouldUpdate(changedProperties) {
    if (changedProperties.has('expanded') && changedProperties.size === 1) {
      return false;
    }
    return true;
  }

  // disable shadow-dom
  createRenderRoot() {
    return this;
  }
}

请注意,我还使用影子dom,不确定是否会改变解决方案。我正在使用精简元素2.2.1。

1 个答案:

答案 0 :(得分:0)

想法是不要使用 LitElement的 static properties@Property装饰器。这样编写自己的属性实现:

class MyDropdown extends LitElement {

  _expanded = false;

  get expanded() {
    return this._expanded;
  }

  set expanded(val) {
    this._expanded = val;

    // Manually setting the property and reflecting attribute.
    if (val) {
      this.setAttribute('expanded', '');
    } else {
      this.removeAttribute('expanded');
    }
  }

  // disable shadow-dom
  createRenderRoot() {
    return this;
  }
}

类似地,每当用户更改属性而不是属性时,您都可以侦听attributeChangedCallback生命周期事件并调整_expanded属性。