使用 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,您應該看到摘要相應地更新!