2024-11-11 vue computed
2024-11-11 vue computed
computed: {
formattedTime() {
為什麼 formattedTime()要寫在 computed?
為什麼 formattedTime() 要寫在 computed 中?
formattedTime() 放在 computed 中,是因為它的值是 從其他數據計算而來的,而且這個計算結果需要根據依賴的數據自動更新。以下是詳細解釋:
1. 自動依賴追蹤(核心原因)
formattedTime()的結果依賴於this.time。- 如果
this.time發生變化,computed屬性會自動重新計算,無需手動更新。
例如:
1 | this.time = 1000; // 當 this.time 變為 1000,formattedTime 自動更新 |
這比把 formattedTime 放在 data 中手動更新要高效且方便。
2. 避免重複計算
computed 屬性會緩存結果,只有當依賴數據發生變化時才重新計算。
- 如果
formattedTime是普通的函數,每次訪問都會重新執行(即使數據沒變化)。 - 而
computed確保只有當this.time改變時才會重新執行,節省性能。
3. 使模板簡潔
如果不使用 computed,需要在模板中直接計算:
1 | <p>時間: {{ Math.floor(time / 60000) }}:{{ Math.floor((time % 60000) / 1000) }}</p> |
這樣會讓模板變得冗長且難以閱讀。
用 computed:
1 | <p>時間: {{ formattedTime }}</p> |
這樣模板會更加清晰直觀。
舉例比較:computed vs data
把 formattedTime 放在 data 中(需要手動更新):
1 | data() { |
這種做法的缺點:
- 需要手動計算並更新
formattedTime。 - 容易漏掉更新邏輯,導致數據和顯示不同步。
- 增加代碼的複雜度。
使用 computed(自動更新):
1 | data() { |
優點:
- 當
this.time改變時,formattedTime自動重新計算。 - 確保數據和顯示同步,無需額外手動更新。
- 代碼簡潔,方便維護。
結論
computed 適合用於 依賴其他數據計算得來的屬性。formattedTime() 是基於 this.time 計算得來的,因此放在 computed 中是最佳選擇。
為什麼是 this.time 改變時 就會執行 formattedTime?
為什麼 this.time 改變時會觸發 formattedTime?
這是因為 Vue 的 響應式系統。Vue 會追蹤數據(例如 this.time)與 computed 屬性之間的依賴關係,當數據發生變化時,會自動重新計算依賴於這些數據的 computed 屬性。
詳細解釋
1. 響應式數據
this.time 是 Vue 中的響應式數據,當它的值改變時,Vue 會觸發與之相關的更新。
例如:
1 | data() { |
2. 依賴追蹤
在 formattedTime 中,我們引用了 this.time:
1 | formattedTime() { |
當 formattedTime() 第一次執行時,Vue 的響應式系統會記錄它依賴了 this.time。
3. 自動更新
當 this.time 改變時,Vue 會檢查哪些 computed 屬性依賴於 this.time,並自動重新計算這些屬性。例如:
1 | this.time = 1000; // 修改響應式數據 |
這時,Vue 檢測到 formattedTime() 依賴於 this.time,就會自動重新執行 formattedTime(),以便更新最新的時間格式。
Vue 的響應式系統如何做到的?
數據代理
當你定義了data,Vue 會通過Object.defineProperty或Proxy將每個屬性轉為響應式的:- 當你讀取屬性(如
this.time)時,Vue 記錄依賴。 - 當你修改屬性時,Vue 通知所有依賴於它的地方重新計算或更新。
- 當你讀取屬性(如
依賴收集
Vue 在計算computed屬性時,會動態追蹤哪些數據被訪問,並把這些數據和computed屬性關聯起來。觸發更新
當某個響應式數據(如this.time)改變時,Vue 通知所有依賴它的computed屬性重新計算,並更新綁定的模板內容。
舉例:數據與 computed 的關係
假設你有以下代碼:
1 | data() { |
在模板中使用:
1 | <p>{{ formattedTime }}</p> |
- 當
this.time是0時,formattedTime的結果是0。 - 當你執行
this.time = 10時:- Vue 檢測到
this.time改變。 - Vue 自動重新執行
formattedTime(),結果變為20,並更新顯示的內容。
- Vue 檢測到
如果不用 computed,需要怎麼做?
如果你不用 computed,每次更新 this.time,都需要手動更新格式化的結果,例如:
1 | data() { |
這樣做:
- 增加代碼的冗餘和複雜度。
- 容易出錯,例如忘記更新
formattedTime時,UI 會顯示舊數據。
結論
當你把 formattedTime 放在 computed 中,Vue 幫你自動處理:
- 追蹤
this.time與formattedTime的依賴關係。 - 當
this.time改變時,自動更新formattedTime。
這是 Vue 提供的響應式特性,讓代碼更加簡潔和高效。
computed 適合用於 依賴其他數據計算得來的屬性 ?
什麼是 computed?
computed 是 Vue 中用來定義「計算屬性」的工具。這些屬性不是直接儲存在 data 裡,而是依賴於其他 data 或屬性計算得來的值。
「依賴其他數據計算得來的屬性」的意思
這表示 computed 屬性的值是根據其他響應式數據(例如 data 中的值)動態計算的。當這些響應式數據改變時,computed 屬性會自動重新計算,並更新顯示。
舉個例子
假設我們有一個網頁,讓使用者輸入名字和姓氏,並顯示全名。
1. 沒有使用 computed 的寫法
1 | data() { |
每次 firstName 或 lastName 改變時,你必須手動呼叫 updateFullName() 更新 fullName:
1 | this.firstName = 'Jane'; |
這樣會造成:
- 代碼冗長:每次數據改變都要手動更新。
- 容易出錯:如果忘記呼叫
updateFullName(),顯示的fullName就會是舊值。
2. 使用 computed 的寫法
1 | data() { |
在模板中直接使用 fullName:
1 | <p>全名:{{ fullName }}</p> |
當你修改 firstName 或 lastName 時,Vue 自動重新計算 fullName,無需手動更新:
1 | this.firstName = 'Jane'; |
為什麼 computed 適合用於依賴其他數據計算的屬性?
自動更新:
當依賴的數據(如firstName或lastName)改變時,computed屬性會自動重新計算,不需要額外的邏輯。性能優化:
computed屬性有緩存機制,當依賴的數據沒有變化時,不會重新執行計算邏輯,節省資源。代碼簡潔:
你不需要手動撰寫更新邏輯(例如updateFullName方法),代碼更易於維護。
更多實例
例子 1:根據數據計算得來的值
1 | data() { |
當 price 或 quantity 改變時,totalPrice 自動更新。
例子 2:格式化數據
1 | data() { |
當 time 改變時,formattedTime 自動以特定格式更新。
結論
computed 適合用於「依賴其他數據的屬性」,因為:
- 它能動態計算值,並且在依賴的數據改變時自動更新。
- 它有緩存機制,提升性能。
- 代碼簡潔易懂,不需要手動處理更新邏輯。
如果屬性不需要依賴其他數據,或者只需一次性初始化,那麼可以直接放在 data 中,而不是 computed。