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
2會員
70內容數
分享生活趣事~
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
卡關的人生 的其他內容
本文深入探討 Vue.js 中的響應式原理,特別是 Composition API 中的 ref() 和 reactive() 使用。通過示例分析這些概念,並比較二者的優缺點,幫助開發者更清晰地理解響應式狀態的管理與最佳實踐。瞭解如何有效地聲明和管理響應式狀態,對於提升 Vue 開發的效率至關重要。
本文介紹了 Vue 的模板語法及虛擬 DOM 概念。學習如何使用 Vue 進行聲明式渲染,以及模板如何轉換為高效的 JavaScript 代碼。探討各種綁定方法、指令及安全注意事項,幫助開發者構建高效動態用戶界面並提升應用性能。文章深入淺出,適合想進一步瞭解 Vue 的開發者。
這篇文章將介紹如何創建和管理 Vue 應用程式的基本概念,包括根組件的概念、如何掛載應用程式及應用程式的配置選項。將探討多個應用實例的使用情境,並解釋如何在同一頁面上共存不同的 Vue 應用程式。透過範例和深入的說明,讀者將能夠理解 Vue 應用程式的組織結構和應用範圍內的資產管理。
隨著AI工具的快速發展,學習新的程式語言變得更為簡便。這篇文章帶你瞭解如何使用Vue.js來建立單頁應用(SPA),並提供環境建置的詳細步驟,包括Node.js的安裝、使用NPM管理套件以及如何透過CDN簡化Vue的應用設置。
Vue是一個前端框架,發音如View,幫助你有效率地開發任何複雜性的使用者介面 由前Google工程師 尤雨溪(Evan You) 邊工作邊開發出來的開源框架,好厲害! 還在耍廢嗎?一起來學習吧~ 期待有朝一日能應徵上遠端工作 www ~ 下面的範例是什麼? // main.js 或 main.
本文深入探討 Vue.js 中的響應式原理,特別是 Composition API 中的 ref() 和 reactive() 使用。通過示例分析這些概念,並比較二者的優缺點,幫助開發者更清晰地理解響應式狀態的管理與最佳實踐。瞭解如何有效地聲明和管理響應式狀態,對於提升 Vue 開發的效率至關重要。
本文介紹了 Vue 的模板語法及虛擬 DOM 概念。學習如何使用 Vue 進行聲明式渲染,以及模板如何轉換為高效的 JavaScript 代碼。探討各種綁定方法、指令及安全注意事項,幫助開發者構建高效動態用戶界面並提升應用性能。文章深入淺出,適合想進一步瞭解 Vue 的開發者。
這篇文章將介紹如何創建和管理 Vue 應用程式的基本概念,包括根組件的概念、如何掛載應用程式及應用程式的配置選項。將探討多個應用實例的使用情境,並解釋如何在同一頁面上共存不同的 Vue 應用程式。透過範例和深入的說明,讀者將能夠理解 Vue 應用程式的組織結構和應用範圍內的資產管理。
隨著AI工具的快速發展,學習新的程式語言變得更為簡便。這篇文章帶你瞭解如何使用Vue.js來建立單頁應用(SPA),並提供環境建置的詳細步驟,包括Node.js的安裝、使用NPM管理套件以及如何透過CDN簡化Vue的應用設置。
Vue是一個前端框架,發音如View,幫助你有效率地開發任何複雜性的使用者介面 由前Google工程師 尤雨溪(Evan You) 邊工作邊開發出來的開源框架,好厲害! 還在耍廢嗎?一起來學習吧~ 期待有朝一日能應徵上遠端工作 www ~ 下面的範例是什麼? // main.js 或 main.
你可能也想看
Google News 追蹤
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
各位使用 Vue.js 開發的小夥伴們,你們都怎麼實作父子層組件資料的雙向綁定呢?如果你還在寫 prop + emit 的話,不妨進來看看吧。
就是指變數可以被訪問和使用的範圍,來說一下var、let和const的作用域差異。 var :function example() { console.log(x); // 輸出: undefined 因為變量提升造成的 var x = 5; } 函數作用域或全域作用域 可以重複宣告
Thumbnail
本章節旨在介紹TypeScript中的函數,包括其基本結構、如何呼叫函數、函數的參數以及函數的返回值等相關概念。通過本章節,讀者可以學習到如何在TypeScript中使用不同的方式來定義函數,如函數聲明、函數表達式、箭頭函數和匿名函數等。
Thumbnail
本章節旨在介紹TypeScript的基本語法,包括一般結構、程式進入點、註解以及變數的定義和賦值。這些知識將幫助讀者瞭解TypeScript的基本架構,並且可以開始使用TypeScript進行開發。
Thumbnail
因為最近想嘗試編碼風格,於是就選了一套比較"不嚴格"的輔助工具來摸索。 編輯器 VS CODE 框架 VUE3 打包工具 VITE 編碼風格 Standard 環境 version { "nodejs":"v18.18.0", "npm":"9.8.1" }
Thumbnail
平常我們在 html 上常看到的例如 v-for、v-model 等等... 也是VUE已經幫我們定義好的指令,而這次我們可以依這自己的需求來建立。 此功能屬於較進階的功能,因此實戰中會比較少見,市面上還是有不少完善的套件能達到同樣效果,建議可以先往這方面察找
Thumbnail
我們在實作中,難免會遇到在不同組件中,卻有需求相同的資料格式,因此 mixins 可以達到我們的需求,除了 data 以外也包含了 methods 可以共用,舉例來說,學生資料可能會在,班級跟社團內被使用,當我們要撰寫元件時,就可以省略多餘的 data 定義。
Thumbnail
前幾篇討論到各種裝飾器的用法,本文將介紹另外一種裝飾器,可以將方法轉換成屬性來使用。 property也可以動態的取出物件的值,隨著時間或其他運算改變所產生的值,讓我們繼續往下看更多介紹吧。
Thumbnail
本文將介紹自定函式及應用,利用程式範例解釋為什麼要用到自定函式 自定函式好處當然就是,讓你的程式碼看起來比較簡潔,在重複使用到的程式碼區塊,可以包裝成函式,讓你重複使用它。
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
各位使用 Vue.js 開發的小夥伴們,你們都怎麼實作父子層組件資料的雙向綁定呢?如果你還在寫 prop + emit 的話,不妨進來看看吧。
就是指變數可以被訪問和使用的範圍,來說一下var、let和const的作用域差異。 var :function example() { console.log(x); // 輸出: undefined 因為變量提升造成的 var x = 5; } 函數作用域或全域作用域 可以重複宣告
Thumbnail
本章節旨在介紹TypeScript中的函數,包括其基本結構、如何呼叫函數、函數的參數以及函數的返回值等相關概念。通過本章節,讀者可以學習到如何在TypeScript中使用不同的方式來定義函數,如函數聲明、函數表達式、箭頭函數和匿名函數等。
Thumbnail
本章節旨在介紹TypeScript的基本語法,包括一般結構、程式進入點、註解以及變數的定義和賦值。這些知識將幫助讀者瞭解TypeScript的基本架構,並且可以開始使用TypeScript進行開發。
Thumbnail
因為最近想嘗試編碼風格,於是就選了一套比較"不嚴格"的輔助工具來摸索。 編輯器 VS CODE 框架 VUE3 打包工具 VITE 編碼風格 Standard 環境 version { "nodejs":"v18.18.0", "npm":"9.8.1" }
Thumbnail
平常我們在 html 上常看到的例如 v-for、v-model 等等... 也是VUE已經幫我們定義好的指令,而這次我們可以依這自己的需求來建立。 此功能屬於較進階的功能,因此實戰中會比較少見,市面上還是有不少完善的套件能達到同樣效果,建議可以先往這方面察找
Thumbnail
我們在實作中,難免會遇到在不同組件中,卻有需求相同的資料格式,因此 mixins 可以達到我們的需求,除了 data 以外也包含了 methods 可以共用,舉例來說,學生資料可能會在,班級跟社團內被使用,當我們要撰寫元件時,就可以省略多餘的 data 定義。
Thumbnail
前幾篇討論到各種裝飾器的用法,本文將介紹另外一種裝飾器,可以將方法轉換成屬性來使用。 property也可以動態的取出物件的值,隨著時間或其他運算改變所產生的值,讓我們繼續往下看更多介紹吧。
Thumbnail
本文將介紹自定函式及應用,利用程式範例解釋為什麼要用到自定函式 自定函式好處當然就是,讓你的程式碼看起來比較簡潔,在重複使用到的程式碼區塊,可以包裝成函式,讓你重複使用它。