計算屬性 computed
說明
使用 computed
可以讓 template
顯示更簡潔或變數更利落。要先引入 computed
再操作,computed
是一個函式,需要 return
一個計算後的值。
computed
若是計算 資料響應 reactive && ref 的值,當 資料響應 reactive && ref 改變時,computed
的值也會同時更新。
vue
<script>
import { computed } from 'vue'
const computedState = computed(() => '計算屬性')
console.log(computedState.value) // '計算屬性'
</script>
與 ref 相同
computed
返回的值,就是一個與 資料響應 reactive && ref 的 ref
相同特性的值,在 template
會自動解 .value
,但 <script>
操作還是需要 .value
來訪問。
例子
vue
<script setup>
import { reactive, computed } from 'vue'
const users = reactive([
{ id: 0, name: 'naiky', age: 37 },
{ id: 1, name: 'niki', age: 7 },
])
const user0Age = computed(() => {
return users[0].age > 20 ? 'old' : 'young'
})
</script>
<template>
<div>
<!-- ⛔ template 太複雜 -->
<span>
{{ users[0].age > 20 ? 'old' : 'young' }}
</span>
<!-- 👍 use computed -->
<span>
{{ user0Age }}</div>
</span>
</template>
計算緩存特性
會發現使用 computed
或 function
方法,都可以達到一樣的計算結果,但 computed
有「緩存」效果,當「值」沒改變時,都會返回相同的「值」不會再重新計算。而 function
方法,每次渲染都會執行一次。
效能好
若有「緩存」的需求,使用 computed
「效能」會好過 function
。
vue
<script setup>
import { reactive, ref, computed } from 'vue'
const nowSpaceState = ref(false)
const now = computed(() => new Date())
function nowFunc() {
return new Date()
}
</script>
<template>
<!-- use computed -->
<div>{{ now }}</div>
<!-- nowSpaceState use nowFunc-->
<button @click="nowSpaceState = !nowSpaceState">
顯示 / 隱藏 `nowSpaceState`
</button>
<div v-if="nowSpaceState">
{{ nowFunc() }}
</div>
</template>
⛔ 可修改的計算屬性
將 computed
函式內部設為 {}
就可以寫入 getter
、setter
,物件屬性定義 object.defineproperty 的 getter 與 setter 就是它的底層原理。
vue
<script setup>
import { reactive, ref, computed } from 'vue'
const user = reactive({
firstName: 'naiky',
lastName: 'ding',
})
const fullName = computed({
get() {
return `${user.firstName} ${user.lastName}`
},
set(newFullName) {
// 解構賦值的寫法
;[user.firstName, user.lastName] = newFullName.split(' ')
},
})
fullName.value = 'niki lo'
</script>
<template>
{{ fullName }}
</template>
computed 應該「唯讀」
使用 computed
時,最佳的作法是不應該產生 side effect 副作用,computed
只能是回傳計算過的資料,若是修改資料來源,就失去意義了。
注意
應避免修改 computed
的「值」。