现在你已经掌握了一些基础知识,我们将介绍一个更复杂的元素。在本教程的剩余部分,你将构建一个待办事项列表组件。这里我们为你的待办事项列表提供了一些样板代码。
由于列表项是组件的私有数据,_listItems 属性被定义为_内部响应式状态_。它的工作方式与响应式属性相同,但不会作为特性暴露,也不应从组件外部访问。更多信息请参见公共属性和内部状态。
你可以在 Lit 表达式中使用标准 JavaScript 来创建条件或重复模板。在这一步中,你将使用 map() 将数据数组转换为重复模板。
渲染列表项。
在无序列表(<ul>)的开始和结束标签之间添加以下表达式。
${this._listItems.map((item) => html`<li>${item.text}</li>` )} 注意 map() 回调中嵌套的 html。更多信息请参见列表和重复模板。
添加点击处理器。
我们提供了一个输入框和一个 Add 按钮,但它们还没有连接起来。添加 input 属性和按钮的事件处理器方法:
query('#newitem')input!: HTMLInputElement;
addToDo() { this._listItems = [...this._listItems, {text: this.input.value, completed: false}]; this.input.value = '';} get input() { return this.renderRoot?.querySelector('#newitem') ?? null;}
addToDo() { this._listItems = [...this._listItems, {text: this.input.value, completed: false}]; this.input.value = '';} @query 装饰器(在代码的 TypeScript 版本中使用)是获取组件内部 DOM 中节点引用的便捷方式。它等同于 JavaScript 版本中的这段代码:
get input() { return this.renderRoot?.querySelector('#newitem') ?? null;} 尝试输入一个新项目并点击 Add。
修改对象和数组。
注意 addToDo() 没有修改 _listItems 数组,而是创建了一个包含新项目的新数组。使用这种不可变数据模式可以确保组件能看到新数据。更多信息请参见修改对象和数组。