我们在这里定义了一个计算属性 publishedBooksMessage
。computed()
方法期望接收一个 getter
函数,返回值为一个计算属性 ref
。和其他一般的 ref
类似,你可以通过 publishedBooksMessage.value
访问计算结果。计算属性 ref
也会在模板中自动解包,因此在模板表达式中引用时无需添加 .value
。
Vue 的计算属性会自动追踪响应式依赖。它会检测到 publishedBooksMessage
依赖于 author.books
,所以当 author.books
改变时,任何依赖于 publishedBooksMessage
的绑定都会同时更新。
<script setup>
import { reactive, computed } from 'vue'
const author = reactive({
books: [
'Vue 2 - Advanced Guide'
]
})
// 一个计算属性 ref
const publishedBooksMessage = computed(() => {
return author.books.length > 0 ? 'Yes' : 'No'
})
</script>
<template>
<span>{{ publishedBooksMessage }}</span>
</template>
不同之处在于计算属性值会基于其响应式依赖被缓存。一个计算属性仅会在其响应式依赖更新时才重新计算。这意味着只要 author.books
不改变,无论多少次访问 publishedBooksMessage
都会立即返回先前的计算结果,而不用重复执行 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>
- 不要在
getter
中做异步请求或者更改 DOM!- 计算属性的返回值应该被视为只读的,并且永远不应该被更改——应该更新它所依赖的源状态以触发新的计算