使用 Vue 計算屬性

在這篇文章中,我們將新增一個計數器,使用 Vue 的計算屬性來顯示已完成的任務項數量。計算屬性的工作原理類似於方法,但只有在它們的依賴項之一發生更改時才會重新執行。

先決條件

熟悉核心 HTMLCSSJavaScript 語言,瞭解 終端/命令列

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 數量,並返回一個報告此數量的字串。

js
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 狀態更新為當前狀態的反面

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

Our app, with a completed todo counter added. It currently reads 3 out of 5 items completed

總結

在這篇文章中,我們使用了計算屬性,為我們的應用程式添加了一個不錯的小功能。但是,我們還有更重要的事情要做——在下一篇文章中,我們將研究條件渲染,以及如何使用它在我們需要編輯現有待辦事項時顯示編輯表單。