使用 Vue 计算属性
在这篇文章中,我们将添加一个计数器,使用 Vue 的计算属性来显示已完成的任务项数量。计算属性的工作原理类似于方法,但只有在它们的依赖项之一发生更改时才会重新运行。
先决条件 |
熟悉核心 HTML、CSS 和 JavaScript 语言,了解 终端/命令行。 Vue 组件以 JavaScript 对象的组合形式编写,这些对象管理应用程序的数据,以及基于 HTML 的模板语法,该语法映射到底层的 DOM 结构。对于安装,以及使用 Vue 的一些更高级的功能(如单文件组件或渲染函数),您需要一个安装了 node + npm 的终端。 |
---|---|
目标 | 学习如何使用 Vue 计算属性。 |
使用计算属性
这里的目标是添加待办事项列表的摘要计数。这对用户来说可能很有用,同时也有助于为辅助技术标记列表。如果我们的待办事项列表中有 5 项,其中 2 项已完成,那么我们的摘要可以显示为“已完成 2 项,共 5 项”。虽然这样做可能很诱人
<h2>
{{ToDoItems.filter(item => item.done).length}} out of
{{ToDoItems.length}} items completed
</h2>
它将在每次渲染时重新计算。对于像这样的小型应用程序,这可能无关紧要。对于大型应用程序,或者当表达式更复杂时,这可能会导致严重的性能问题。
更好的解决方案是使用 Vue 的 计算属性。计算属性的工作原理类似于方法,但只有在它们的依赖项之一发生更改时才会重新运行。在我们的例子中,只有在 ToDoItems
数组发生更改时才会重新运行。
要创建计算属性,我们需要在组件对象中添加一个 computed
属性,就像我们之前使用过的 methods
属性一样。
添加摘要计数器
在 methods
属性下方,将以下代码添加到您的 App
组件对象中。列表摘要方法将获取已完成的 ToDoItems
数量,并返回一个报告此数量的字符串。
computed: {
listSummary() {
const numberFinishedItems = this.ToDoItems.filter((item) =>item.done).length
return `${numberFinishedItems} out of ${this.ToDoItems.length} items completed`
}
}
现在,我们可以直接将 {{listSummary}}
添加到我们的模板中;我们将将其添加到一个 <h2>
元素中,位于我们的 <ul>
元素上方。我们还将添加一个 id
和一个 aria-labelledby
属性,将 <h2>
元素的内容指定为 <ul>
元素的标签。
按照描述添加 <h2>
元素,并更新您 App
模板中的 <ul>
元素,如下所示
<h2 id="list-summary">{{listSummary}}</h2>
<ul aria-labelledby="list-summary" class="stack-large">
<li v-for="item in ToDoItems" :key="item.id">
<to-do-item
:label="item.label"
:done="item.done"
:id="item.id"></to-do-item>
</li>
</ul>
您现在应该在应用程序中看到列表摘要,并且当您添加更多待办事项时,总项数也会更新!但是,如果您尝试选中和取消选中一些项,您将发现一个错误。目前,我们实际上并没有跟踪“已完成”数据,因此已完成项的数量不会发生变化。
跟踪对“已完成”的更改
我们可以使用事件来捕获复选框更新并相应地管理我们的列表。
由于我们不是依赖于按钮按下触发更改,我们可以将 @change
事件处理程序附加到每个复选框,而不是使用 v-model
。
更新 ToDoItem.vue
中的 <input>
元素,使其看起来像这样。
<input
type="checkbox"
class="checkbox"
:id="id"
:checked="isDone"
@change="$emit('checkbox-changed')" />
由于我们只需要发出复选框已被选中,我们可以将 $emit()
内联包含。
在 App.vue
中,在 addToDo()
方法下方添加一个名为 updateDoneStatus()
的新方法。此方法应接受一个参数:待办事项 id。我们要找到具有匹配 id
的项,并将它的 done
状态更新为当前状态的反面
updateDoneStatus(toDoId) {
const toDoToUpdate = this.ToDoItems.find((item) => item.id === toDoId)
toDoToUpdate.done = !toDoToUpdate.done
}
我们希望在 ToDoItem
发出 checkbox-changed
事件时运行此方法,并将它的 item.id
作为参数传递。更新您的 <to-do-item></to-do-item>
调用,如下所示
<to-do-item
:label="item.label"
:done="item.done"
:id="item.id"
@checkbox-changed="updateDoneStatus(item.id)">
</to-do-item>
现在,如果您选中 ToDoItem
,您应该看到摘要相应地更新!