向模板中的列表项添加事件监听器有多种方式。你还需要确保事件处理器能够识别事件与哪个项相关。本步骤展示了一种实现方式。

示例目前在 things 状态属性中有一个字符串数组。每个字符串都渲染为带有"删除"按钮的列表项,但该按钮还没有任何功能。

首先,创建一个在按钮被点击时调用的方法。该方法应接受一个项的索引作为参数,并从 things 数组中移除该项。

// my-element.ts
class MyElement extends LitElement {
private _deleteThing(index: number) {
this.things = this.things.filter((_, i) => i !== index);
}
}
// my-element.js
class MyElement extends LitElement {
_deleteThing(index) {
this.things = this.things.filter((_, i) => i !== index);
}
}

使用不可变数据模式来触发更新。

filter() 数组方法返回一个新数组并赋值给 this.things。由于存储在 this.things 中的引用发生了变化,Lit 会在调用 _deleteThing() 时知道需要更新组件。如果使用 splice() 等数组方法直接修改数组,则必须手动请求更新。更多信息请参阅修改对象和数组属性

现在在映射数组时为每一项的按钮注册事件处理器。

// my-element.ts
render() {
return html`
<ul>
${map(
this.things,
(thing, index) => html`
<li>
${thing}
<button @click=${() => this._deleteThing(index)}>Delete</button>
</li>
`
)}
</ul>
`;
}
// my-element.js
render() {
return html`
<ul>
${map(
this.things,
(thing, index) => html`
<li>
${thing}
<button @click=${() => this._deleteThing(index)}>Delete</button>
</li>
`
)}
</ul>
`;
}

现在点击删除按钮应该可以移除该项了。注意这里使用了内联箭头函数来创建闭包,这样每个列表项都能获得一个以其自身索引调用 _deleteThing 的函数。

虽然闭包在大多数情况下都适用,但也有其他方式可以实现这种行为。

例如,你可以为触发事件的元素添加属性或特性。事件处理器随后可以通过 event.target 访问该数据。当监听冒泡事件时,可以使用事件委托来避免在每个项上都附加事件监听器。更多信息请参阅监听重复模板中触发的事件