vue3,

Vue3 計算屬性 computed

Tony Tony Follow Sep 27, 2020 · 1 min read
 Vue3 計算屬性 computed
Share this

根據官方文件,computed 設計的初衷是避免開發者在樣板區塊放入太多的邏輯。我們在管理數據時會希望資料來源一致,假如有兩個變數,變數2的數值是可以經由變數1推導得到,我們就該將它們簡化成一個變數加上一個computed物件,日後就不必維護兩個變數。

語法

computed接受一個函數參數,返回是一個ref的實例,預設是只讀的。

const computedVariable = computed(()=>{//do somethind 
                                        return value
                                        })

範例

假設我們有一個會員資料頁面,其中一個欄位是出生年,同時要顯示民國年和西元年,我們當然可以儲存兩個值在後台,然後分別綁定到頁面上,不過這顯示不是一個很好的做法,因為要維護兩個變數。

因為西元年可以藉由民國年加上1911推導而來,因此我們可以使用computed函數從民國年去計算得到西元年。

<script>
import {computed} from 'vue'
export default {
  setup () {
    const birth=ref(0)
    const birthInAD=computed(()=>birth+1911)
    return {birth,birthInAD}
  }
}
</script>

雖然computed函數返回的是一個ref物件,不過預設是不能修改,重新對computed的變數賦值會產生一個 Vue warning。

<script>
import {computed} from 'vue'
export default {
  setup () {
    const birth=ref(0)
    const birthInAD=computed(()=>birth+1911)
    birthInAD.val = 2020
    console.log('民國出生年:',birth)
    console.log('西元出生年:',birthInAD)
    return {birth,birthInAD}
  }
}
</script>

輸出結果

[ Vue warn] : Computed property was assigned to but it has no setter.
民國出生年: 0
西元出生年: 1911

getter & setter

為什麼computed函數的返回值預設會只讀,我們可以從上面的例子開始討論。

首先,我們呼叫了computed創立了一個birthInAD的變數,同時告訴了coumputed函數兩件事,第一、birthInAD的值是由birth變數推導而來,第二、推導的公式為 birthInAD = birth+1911

接著我們可能因為某種原因必須更新birthInAD的值,但是被拒絕了,為什麼呢?是不是因為我們建立了birthInAD和birth兩者的推導關係,如果只更新birthInAD的數值就會使得這個關係被破壞,很明顯不合理,因此我們必須要反推導birth的數值並且同時更新。

也就是說,原先我們建立的是單向的推導關係,現在要把關係變為雙向。

我們可以傳入一個擁有get和set屬性的物件給computed函數,創建一個可以重新賦值的computed物件

<script>
import {computed, ref} from 'vue'
export default {
  setup () {
    const birth=ref(0)
    const birthInAD=computed({
    get:()=> birth + 1911
    set:(val)=>{birth.value = val - 1911}
    })
    birthInAD.val = 2020
    console.log('民國出生年:',birth)
    console.log('西元出生年:',birthInAD)
    // 輸出結果
    // 民國出生年: 89
    // 西元出生年: 2020
    return {birth,birthInAD}
  }
}
</script>
Join Newsletter
Get the latest news right in your inbox. We never spam!
Tony
Written by Tony Follow
Hi, I am Tony, the author of Learning Journey blog. I hope you like what I sharing!