Vue 的 ref 什么时候自动解包

ref 在模板中的解包
当 ref 在模板中作为顶层 property 被访问时,它们会被自动“解包”,所以不需要使用 .value。下面是之前的计数器例子,用 ref() 代替:
<script setup>import { ref } from 'vue'const count = ref(0)function increment() {count.value++}script><template><button @click="increment">{{ count }}button>template>
请注意,仅当 ref 是模板渲染上下文的顶层 property 时才适用自动“解包”。例如, foo 是顶层 property,但 object.foo 不是。
所以我们给出以下 object:
const object = { foo: ref(1) }下面的表达式将不会像预期的那样工作:
{{ object.foo + 1 }}渲染的结果会是一个 [object Object],因为 object.foo 是一个 ref 对象。我们可以通过让 foo 成为顶级 property 来解决这个问题:
const { foo } = object{{ foo + 1 }}现在渲染结果将是 2。
需要注意的是,如果一个 ref 是文本插值(即一个 {{ }} 符号)计算的最终值,它也将被解包。因此下面的渲染结果将为 1:
{{ object.foo }}这只是文本插值的一个方便功能,相当于 {{ object.foo.value }}。
ref 在响应式对象中的解包
当一个 ref 作为一个响应式对象的 property 被访问或更改时,它会自动解包,因此会表现得和一般的 property 一样:
const count = ref(0)const state = reactive({count})console.log(state.count) // 0state.count = 1console.log(count.value) // 1
如果将一个新的 ref 赋值给一个关联了已有 ref 的 property,那么它会替换掉旧的 ref:
const otherCount = ref(2)state.count = otherCountconsole.log(state.count) // 2// 原始 ref 现在已经和 state.count 失去联系console.log(count.value) // 1
只有当嵌套在一个深层响应式对象内时,才会发生 ref 解包。当其作为浅层响应式对象的 property 被访问时不会解包。
数组和集合类型的 ref 解包
不像响应式对象,当 ref 作为响应式数组或像 Map 这种原生集合类型的元素被访问时,不会进行解包。
const books = reactive([ref('Vue 3 Guide')])// 这里需要 .valueconsole.log(books[0].value)const map = reactive(new Map([['count', ref(0)]]))// 这里需要 .valueconsole.log(map.get('count').value)
评论
