响应式属性

Permalink to "响应式属性"

Lit 在原生 Web Component 回调之上引入了一组渲染生命周期回调方法。当声明的 Lit 响应式属性发生变化时,这些回调会被触发。

要了解更多关于 Lit 响应式更新周期的内容,请参阅 Lit 生命周期文档

要使用此功能,你必须静态声明哪些属性是响应式属性——当这些属性变化时会触发生命周期渲染:

rating-element.

Permalink to "rating-element."
import {customElement, property} from 'lit/decorators.js';

export class RatingElement extends LitElement {
...
@property({type: Number})
rating = 0;

@property({type: String, reflect: true})
vote: 'up'|'down'|null = null;

// 移除 observedAttributes() 和 attributeChangedCallback()
// 移除 set rating() 和 get rating()
// 移除 set vote() 和 get vote()
// 移除 _rating 和 _vote 私有类成员
...
export class RatingElement extends LitElement {
...
static properties = {
rating: {type: Number},
vote: {type: String, reflect: true},
};

constructor() {
super();
this.rating = 0;
this.vote = null;
}

// 移除 observedAttributes() 和 attributeChangedCallback()
// 移除 set rating() 和 get rating()
// 移除 set vote() 和 get vote()
// 移除 _rating 和 _vote 私有类成员
...

在这里,你:

以属性形式传递复杂对象。

通常来说,以属性而非 attribute 的形式传递复杂对象是最佳实践。更多关于响应式属性的 attribute 转换内容,请阅读 Lit 文档

此外,vote 属性上的 reflect 标志会自动更新宿主元素的 vote attribute,这正是你之前在 vote setter 中手动更新的。反射 vote attribute 是必要的,这样才能应用 :host([vote=up]) 样式。

willUpdate 生命周期回调

Permalink to "willUpdate 生命周期回调"

现在在 willUpdate() Lit 生命周期方法中,当 vote 属性变化时更新 rating

rating-element.

Permalink to "rating-element."
// 导入 PropertyValues
import {LitElement, html, css, PropertyValues} from 'lit';
...
willUpdate(changedProps: PropertyValues<this>) {
if (changedProps.has('vote')) {
const newValue = this.vote;
const oldValue = changedProps.get('vote');

if (newValue === 'up') {
if (oldValue === 'down') {
this.rating += 2;
} else {
this.rating += 1;
}
} else if (newValue === 'down') {
if (oldValue === 'up') {
this.rating -= 2;
} else {
this.rating -= 1;
}
}
}
}
willUpdate(changedProps) {
if (changedProps.has('vote')) {
const newValue = this.vote;
const oldValue = changedProps.get('vote');

if (newValue === 'up') {
if (oldValue === 'down') {
this.rating += 2;
} else {
this.rating += 1;
}
} else if (newValue === 'down') {
if (oldValue === 'up') {
this.rating -= 2;
} else {
this.rating -= 1;
}
}
}
}

这里的逻辑与之前的 vote setter 逻辑相同,只是移到了 willUpdate() 生命周期方法中。

willUpdate() 方法在每次响应式属性变化时、render() 之前调用。由于 LitElement 会批量处理属性变化并使渲染变为异步,因此在 willUpdate() 中对响应式属性(如 this.rating)的更改不会触发不必要的渲染生命周期调用。

恭喜,你现在应该有一个可以工作的 Lit Element 了!