事件监听器

Permalink to "事件监听器"

现在你已经移除了 index.html 中的 <template> 元素,重构代码以利用新定义的 render() 方法中的 Lit 模板功能。你可以从使用 Lit 的事件监听器绑定语法开始:

rating-element.

Permalink to "rating-element."
<button
class="thumb_down"
@click=${() => {this.vote = 'down'}}>
...
<button
class="thumb_up"
@click=${() => {this.vote = 'up'}}>

Lit 模板可以通过 @EVENT_NAME 绑定语法为节点添加事件监听器,在本例中,你每次点击这些按钮时都会更新 vote 属性。

你可以在 Lit 表达式文档中了解更多关于 Lit 绑定语法的内容。

接下来:

rating-element.

Permalink to "rating-element."
export class RatingElement extends HTMLElement {
private _rating = 0;
private _vote: 'up'|'down'|null = null;

connectedCallback() {
this.attachShadow({mode: 'open'});
this.render();
}

// 移除 disonnectedCallback 和 _onUpClick、_onDownClick
...
}
export class RatingElement extends HTMLElement {
_rating = 0;
_vote = null;

connectedCallback() {
this.attachShadow({mode: 'open'});
this.render();
}

// 移除 disonnectedCallback 和 _onUpClick、_onDownClick
...
}

你成功移除了:

渲染属性更新

Permalink to "渲染属性更新"

最后,更新属性 setter 以使用 render 方法,这样当属性或 attribute 变化时 DOM 就能更新:

rating-element.

Permalink to "rating-element."
set rating(value) {
this._rating = value;
// 移除命令式设置 innerText 的逻辑
// 因为它在 render() 中处理了
this.render();
}

...

set vote(newValue) {
...

this._vote = newValue;
this.setAttribute('vote', newValue!);
// 在 setter 末尾调用 this.render()
this.render();
}
set rating(value) {
this._rating = value;
// 移除命令式设置 innerText 的逻辑
// 因为它在 render() 中处理了
this.render();
}

...

set vote(newValue) {
...

this._vote = newValue;
this.setAttribute('vote', newValue);
// 在 setter 末尾调用 this.render()
this.render();
}

这不是更新 DOM 最高效的方式。

ratingvote 的 setter 中同步调用 render() 并不是更新 DOM 最高效的方式,但它是展示 LitElement 在何处调用 render() 的好方法(下一步会介绍)。

在这里,你:

现在模板可读性更强了,因为你可以清楚地看到绑定和事件监听器在哪里应用。

你现在应该有一个功能正常的 <rating-button>,当点击点赞时看起来像这样!

点赞和踩评分滑块,值为 6,点赞按钮为绿色