LitElement 不会从父组件更新子组件



我不理解lit的web组件架构中的反应性概念。从其他框架中,我假设下面的示例可以毫无问题地更新,但它不适用于lit

我可以看到,子组件render方法只是最初被调用,而不是再次点击按钮后。但是,即使我通过Web Components DevTools手动调用它,它也不会以新的状态重新渲染。

我需要改变什么来使它工作?

父组件:

import {LitElement, html} from 'lit';
import {customElement, property} from 'lit/decorators.js';
import './show-planets';
@customElement('lit-app')
export class LitApp extends LitElement {
addPlanet() {
this.planetsParent.push('Pluto')
console.log('this.planetsParent', this.planetsParent)
}
@property({type: Array}) planetsParent = ['Mars'];
render() {
return html`
<button @click="${this.addPlanet}">click</button>
<show-planets .planetsChild="${this.planetsParent}"></show-planets>
`;
}
}

子组件:

import {LitElement, html} from 'lit';
import {customElement, property} from 'lit/decorators.js';
@customElement('show-planets')
export class ShowPlanets extends LitElement {
@property({type: Array}) planetsChild = ['Pluto'];
render() {
console.log('this.planetsChild', this.planetsChild);
return html`<h1>Planets are: ${this.planetsChild}</h1>`;
}
}

LitElement的属性系统只观察对引用的更改。递归地监听子属性的变化将是非常昂贵的,特别是对于大型嵌套对象。

因此,设置this.planetsParent的子或孙子属性将不会触发渲染。

那么,如果我们需要更新嵌套的子节点,我们该怎么做呢?不可变数据模式可以帮助我们。

addPlanet() {
const [...rest] = this.planetsParent;
const newItem = 'Pluto';
this.planetsParent = [newItem, ...rest];
}

参考:https://open-wc.org/guides/knowledge/lit-element/rendering/litelement-rendering