EP5 - 計算屬性

更新於 發佈於 閱讀時間約 1 分鐘
Computed Properties 計算屬性,顧名思義是可以計算的屬性?
有時候想想為什麼各種框架會被發明出來~
裡頭的特性應該是要用來解決什麼問題的吧?

這篇有影片可以看耶!

基本範例 - Basic Example

在模板中使用表達式非常方便,但它們適用於簡單的操作。將過多的邏輯放在模板中會使其變得臃腫且難以維護。例如,如果我們有一個包含嵌套數組的物件:

const author = reactive({
name: 'John Doe',
books: [
'Vue 2 - Advanced Guide',
'Vue 3 - Basic Guide',
'Vue 4 - The Mystery'
]
})

我們想要顯示不同的訊息,取決於 author 是否已經有一些書籍:

<template>
<p>Has published books:</p>
<span>{{ author.books.length > 0 ? 'Yes' : 'No' }}</span>
</template>

此時,模板開始變得有點混亂。我們需要稍微看一下才能意識到它根據 author.books 進行計算。更重要的是,如果我們需要在模板中多次包含這計算,不希望重複寫邏輯吧。

這就是為什麼在包含響應式數據的複雜邏輯中,推薦使用計算屬性的原因。以下是相同的範例,重構後的版本:

<script setup>
import { reactive, computed } from 'vue'

const author = reactive({
name: 'John Doe',
books: [
'Vue 2 - Advanced Guide',
'Vue 3 - Basic Guide',
'Vue 4 - The Mystery'
]
})

// 一個計算屬性
const publishedBooksMessage = computed(() => {
return author.books.length > 0 ? 'Yes' : 'No'
})
</script>

<template>
<p>Has published books:</p>
<span>{{ publishedBooksMessage }}</span>
</template>

Try it in the Playground

在這裡,我們聲明了一個計算屬性 publishedBooksMessagecomputed() 函數期望接收一個 getter 函數,並且返回一個計算 ref。類似於普通的 ref,你可以通過 publishedBooksMessage.value 訪問計算結果。計算 ref 也會在模板中自動解包,因此你可以在模板表達式中引用它們而不需要 .value

計算屬性會自動追蹤其響應式依賴項。Vue 知道 publishedBooksMessage 的計算依賴於 author.books,因此當 author.books 改變時,它會更新任何依賴 publishedBooksMessage 的綁定。

相關閱讀:計算屬性的類型化

計算緩存 vs 方法 - Computed Caching vs. Methods

你可能已經注意到,我們可以通過在表達式中調用方法來達到相同的結果:

<template>
<p>{{ calculateBooksMessage() }}</p>
</template>

<script>
// 在組件中
function calculateBooksMessage() {
return author.books.length > 0 ? 'Yes' : 'No'
}
</script>

與計算屬性相比,我們可以將相同的函數定義為一個方法。對於最終結果,這兩種方法確實完全相同。然而,區別在於計算屬性是基於其響應式依賴項進行緩存的。計算屬性僅會在某些響應式依賴項發生變化時重新計算。這意味著只要 author.books 沒有改變,對 publishedBooksMessage 的多次訪問將立即返回之前計算的結果,而無需再次運行 getter 函數。

這也意味著以下計算屬性永遠不會更新,因為 Date.now() 不是響應式依賴項

const now = computed(() => Date.now())

相比之下,每次重新渲染時,方法調用都會執行函數。

為什麼我們需要緩存?

想像一下我們有一個昂貴的計算屬性 list,它需要遍歷一個巨大的數組並進行大量計算。然後,我們可能會有其他依賴於 list 的計算屬性。如果沒有緩存,我們將多次不必要地執行 list 的 getter 函數!在不需要緩存的情況下,請使用方法調用。

  • 方法調用:每次重新渲染時都會執行方法,即使方法的依賴數據沒有變化。這樣可能會導致性能問題,特別是當方法執行時間較長時。
  • 計算屬性:僅在依賴數據變化時重新計算,否則返回緩存的結果。這可以提高性能,避免不必要的計算。

可寫入的計算屬性 - Writable Computed

計算屬性預設是僅有 getter 的。如果你嘗試給計算屬性賦予一個新值,會收到一個運行時警告。在極少數情況下,如果你需要一個「可寫入的」計算屬性,可以通過提供 getter 和 setter 來創建一個:

<script setup>
import { ref, computed } from 'vue'

const firstName = ref('John')
const lastName = ref('Doe')

const fullName = computed({
// getter
get() {
return firstName.value + ' ' + lastName.value
},
// setter
set(newValue) {
// 注意:這裡我們使用了解構賦值語法。
[firstName.value, lastName.value] = newValue.split(' ')
}
})
</script>

現在當你運行 fullName.value = 'John Doe' 時,setter 會被調用並且 firstNamelastName 會相應地更新。

最佳練習 - Best Practices

Getter 應該沒有副作用 - Getters should be side-effect free

請記住,計算屬性的 getter 函數應該僅執行純計算且沒有副作用。例如,不要在計算屬性的 getter 中修改其他狀態、發起異步請求或修改 DOM!可以將計算屬性視為聲明式地描述如何根據其他值來衍生成另一個值,它唯一責任應該是計算並返回該值。在文件的後面部分,我們將討論如何在狀態變更時使用監視器(watchers)來產生副作用。

有趣的範例 Try it in the Playground

避免修改計算屬性的值 - Avoid mutating computed value

從計算屬性返回值是衍生狀態。可以將其視為一個臨時快照,每當源狀態變化時,就會創建一個新的快照。修改快照沒有意義,所以計算屬性的返回值應被視為只讀且永遠不應該被修改,相反,應更新它所依賴的來源狀態來觸發新的計算。

這章節有看得比較懂一點了~
那些不用去F5刷新網頁就可以更新畫面的東東
應該就是類似這種來源更新,畫面自動會更新東東吧 www



留言
avatar-img
留言分享你的想法!
avatar-img
卡關的人生
2會員
73內容數
分享生活趣事~
卡關的人生的其他內容
2024/11/10
Vue 提供了多種動畫技術來提升應用程式的互動性,包括基於 CSS 類別的動畫、基於狀態的動畫,以及使用監視器來動畫化數值。基於類別的動畫可通過動態添加 CSS 類別來觸發,像是觸發按鈕搖動效果。基於狀態的動畫則是透過樣式綁定,根據互動動態調整元素的外觀,例如根據滑鼠位置改變背景顏色。
Thumbnail
2024/11/10
Vue 提供了多種動畫技術來提升應用程式的互動性,包括基於 CSS 類別的動畫、基於狀態的動畫,以及使用監視器來動畫化數值。基於類別的動畫可通過動態添加 CSS 類別來觸發,像是觸發按鈕搖動效果。基於狀態的動畫則是透過樣式綁定,根據互動動態調整元素的外觀,例如根據滑鼠位置改變背景顏色。
Thumbnail
2024/11/09
Web Components 是一組網頁原生 API,允許開發者創建可重複使用的自訂元素。Vue 與 Web Components 是互補的技術,Vue 支援整合和創建自訂元素。
Thumbnail
2024/11/09
Web Components 是一組網頁原生 API,允許開發者創建可重複使用的自訂元素。Vue 與 Web Components 是互補的技術,Vue 支援整合和創建自訂元素。
Thumbnail
2024/11/08
Vue 建議使用模板構建應用程式,但在需要 JavaScript 的全程式化功能時,渲染函數可派上用場。渲染函數通過 h() 函數創建 vnode,h 是 hyperscript 的簡寫,能生成 HTML 的 JavaScript。
Thumbnail
2024/11/08
Vue 建議使用模板構建應用程式,但在需要 JavaScript 的全程式化功能時,渲染函數可派上用場。渲染函數通過 h() 函數創建 vnode,h 是 hyperscript 的簡寫,能生成 HTML 的 JavaScript。
Thumbnail
看更多
你可能也想看
Thumbnail
孩子寫功課時瞇眼?小心近視!這款喜光全光譜TIONE⁺光健康智慧檯燈,獲眼科院長推薦,網路好評不斷!全光譜LED、180cm大照明範圍、5段亮度及色溫調整、350度萬向旋轉,讓孩子學習更舒適、保護眼睛!
Thumbnail
孩子寫功課時瞇眼?小心近視!這款喜光全光譜TIONE⁺光健康智慧檯燈,獲眼科院長推薦,網路好評不斷!全光譜LED、180cm大照明範圍、5段亮度及色溫調整、350度萬向旋轉,讓孩子學習更舒適、保護眼睛!
Thumbnail
創作者營運專員/經理(Operations Specialist/Manager)將負責對平台成長及收入至關重要的 Partnership 夥伴創作者開發及營運。你將發揮對知識與內容變現、影響力變現的精準判斷力,找到你心中的潛力新星或有聲量的中大型創作者加入 vocus。
Thumbnail
創作者營運專員/經理(Operations Specialist/Manager)將負責對平台成長及收入至關重要的 Partnership 夥伴創作者開發及營運。你將發揮對知識與內容變現、影響力變現的精準判斷力,找到你心中的潛力新星或有聲量的中大型創作者加入 vocus。
Thumbnail
先前提到 Quasar 的 Dialog Plugin 很好用,再讓我補充一個用法。
Thumbnail
先前提到 Quasar 的 Dialog Plugin 很好用,再讓我補充一個用法。
Thumbnail
各位使用 Vue.js 開發的小夥伴們,你們都怎麼實作父子層組件資料的雙向綁定呢?如果你還在寫 prop + emit 的話,不妨進來看看吧。
Thumbnail
各位使用 Vue.js 開發的小夥伴們,你們都怎麼實作父子層組件資料的雙向綁定呢?如果你還在寫 prop + emit 的話,不妨進來看看吧。
Thumbnail
平常我們在 html 上常看到的例如 v-for、v-model 等等... 也是VUE已經幫我們定義好的指令,而這次我們可以依這自己的需求來建立。 此功能屬於較進階的功能,因此實戰中會比較少見,市面上還是有不少完善的套件能達到同樣效果,建議可以先往這方面察找
Thumbnail
平常我們在 html 上常看到的例如 v-for、v-model 等等... 也是VUE已經幫我們定義好的指令,而這次我們可以依這自己的需求來建立。 此功能屬於較進階的功能,因此實戰中會比較少見,市面上還是有不少完善的套件能達到同樣效果,建議可以先往這方面察找
Thumbnail
自訂元件生成位置顧名思義就是可以指定部分HTML區塊渲染在特定的畫面上,即使在不同組件也能把A組件內的部分畫面,展現在B組件上,以下方程式舉例。
Thumbnail
自訂元件生成位置顧名思義就是可以指定部分HTML區塊渲染在特定的畫面上,即使在不同組件也能把A組件內的部分畫面,展現在B組件上,以下方程式舉例。
Thumbnail
Vue.js是一種基於MVVM的前端JavaScript框架,類似的框架有React、Angular等。 架設環境 安裝Visual Studio Code(https://code.visualstudio.com/) 安裝Node.js(https://nodejs.org/en/
Thumbnail
Vue.js是一種基於MVVM的前端JavaScript框架,類似的框架有React、Angular等。 架設環境 安裝Visual Studio Code(https://code.visualstudio.com/) 安裝Node.js(https://nodejs.org/en/
Thumbnail
樣板模式的定義極為簡單,卻是大型系統程式、WEB/APP應用框架的設計核心,完美展現設計模式的價值: 簡單、高效、強大。
Thumbnail
樣板模式的定義極為簡單,卻是大型系統程式、WEB/APP應用框架的設計核心,完美展現設計模式的價值: 簡單、高效、強大。
Thumbnail
2023 Vue直播班筆記 - 動態路由Props,接續之前的一般動態路由。分為 "寫死" 及 "彈性" 兩種。
Thumbnail
2023 Vue直播班筆記 - 動態路由Props,接續之前的一般動態路由。分為 "寫死" 及 "彈性" 兩種。
Thumbnail
Vue Router 及 具名視圖,擺脫以往切換依賴 CSS display:none 跟 display:block 互相配合,有時還得搭配 z-index 來調整層級跟 opacity 透明度的麻煩,而 Vue Router 完美的解決了這棘手的問題,且能客製頁面想要呈現的擺飾。
Thumbnail
Vue Router 及 具名視圖,擺脫以往切換依賴 CSS display:none 跟 display:block 互相配合,有時還得搭配 z-index 來調整層級跟 opacity 透明度的麻煩,而 Vue Router 完美的解決了這棘手的問題,且能客製頁面想要呈現的擺飾。
Thumbnail
這系列是我在 2023 六角學院 Vue作品實戰班的筆記,筆記以本人理解的方式記錄。此篇主題為 Slot Props 進階應用 ,其中包含單筆資料、多筆資料。
Thumbnail
這系列是我在 2023 六角學院 Vue作品實戰班的筆記,筆記以本人理解的方式記錄。此篇主題為 Slot Props 進階應用 ,其中包含單筆資料、多筆資料。
Thumbnail
在 Vue 專案中使用 Apollo Graphql Client 從 API 獲取資料,由於資料結構較為複雜,筆者便跟著網路教學使用 codegen 工具自動化產生 TypeScript 型別定義。在某個元件中,需要使用 defineProps 來撰寫型別定義,結果⋯⋯
Thumbnail
在 Vue 專案中使用 Apollo Graphql Client 從 API 獲取資料,由於資料結構較為複雜,筆者便跟著網路教學使用 codegen 工具自動化產生 TypeScript 型別定義。在某個元件中,需要使用 defineProps 來撰寫型別定義,結果⋯⋯
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News