Vue 的 ref 什么时候自动解包
共 1340字,需浏览 3分钟
·
2022-05-25 13:39
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) // 0
state.count = 1
console.log(count.value) // 1
如果将一个新的 ref 赋值给一个关联了已有 ref 的 property,那么它会替换掉旧的 ref:
const otherCount = ref(2)
state.count = otherCount
console.log(state.count) // 2
// 原始 ref 现在已经和 state.count 失去联系
console.log(count.value) // 1
只有当嵌套在一个深层响应式对象内时,才会发生 ref 解包。当其作为浅层响应式对象的 property 被访问时不会解包。
数组和集合类型的 ref 解包
不像响应式对象,当 ref 作为响应式数组或像 Map 这种原生集合类型的元素被访问时,不会进行解包。
const books = reactive([ref('Vue 3 Guide')])
// 这里需要 .value
console.log(books[0].value)
const map = reactive(new Map([['count', ref(0)]]))
// 这里需要 .value
console.log(map.get('count').value)