ref 自动解包
1 什么是解包
通常情况下,如果想要使用 ref
,需要通过 .value
,如 name.value
,解包就是可以不通过 .value
来使用 ref
。
2 手动解包 unref
这是 val = isRef(val) ? val.value : val
计算的一个语法糖。
通过 unref
,如果参数是 ref
,则返回内部值,否则返回参数本身。
3 哪些场景下会自动解包
3.1 ref 在模板中的解包
当 ref
在模板中作为顶层 property 被访问时,它们会被自动解包,所以不需要使用 .value
。
3.2 ref 在响应式对象中的解包
当一个 ref
作为一个响应式对象的 property 被访问或更改时,它会自动解包,因此会表现得和一般的 property 一样:
js
// count 和 state.count 是相关联的,修改其中一个,另一个也相应变化。
const count = ref(0)
const state = reactive({
count
})
console.log(state.count) // 0
state.count = 1
// 注意此时 count 的值也改变了
console.log(count.value) // 1
js
// 此时,count 和 state.count 不是相关联的
const count = ref(0)
const state = reactive({
count: count.value
})
注意,当 count
是一个数组或 Map ref
时,不会自动解包。
3.4 ref 在 defineExpose 中的解包
vue
<script setup>
import { ref } from 'vue'
const a = 1
const b = ref(2)
// 写法一,这种形式与 3.2 中的 state 类似
// const temp = reactive({ a: a, b: b })
// defineExpose(temp)
// 写法二
// defineExpose({
// a: a,
// b: b
// })
// 或者三
defineExpose({
a,
b
})
</script>
vue
<script setup>
import Hello from '#/components/Hello.vue'
const helloRef = ref(null)
console.log(helloRef.value) // null
nextTick(() => {
console.log(helloRef.value.b) // 2
})
function handleClick() {
helloRef.value.b += 1
console.log(helloRef.value.b) // 点击按钮后打印 3,此时hello.vue 中 b 的值变为 3
}
</script>
<template>
<button type="button" @click="handleClick">
click
</button>
<Hello ref="helloRef" />
</template>
4 注意
在依赖注入中,ref
不会自动解包(注入)。