前言 📝

前置知识是要熟悉掌握深层响应式和浅层响应式。如果不是很了解可以先去看小编的另外几篇文章。

传送门 🚥🚥🚥: 🥬 建立一个响应式系统

众所周知,使用ref声明响应式数据,在使用的时候我们需要通过.value去访问。**而所谓的解包,指的是自动访问.value,不需要在通过手动的指定.value去获取值。**例如模板中使用ref类型的数据,就会自动解包。

1. Ref作为 reactive 对象的属性值-自动解包

下面这种情况会自动解包:

1
2
3
4
5
6
7
8
9
10
11
<script setup>
import { ref, reactive } from 'vue'

const count = ref(0)
let objReactive = reactive({
  count
})

// proxy对象
console.log(objReactive.count) // output: 0
</script>
1
2
3
<template>
  <h1>{{ objReactive.count }}</h1>
</template>

在上面的列子中,count(ref对象)作为了objReactive(reactive对象)的属性值,在该属性被访问或者被修改的时候会自动进行解包。

2. 数组和集合里面使用 ref-自动解包

如果将 ref 数据作为 reactvie 数组或者集合的一个元素,此时是不会自动解包的

1
2
3
4
5
6
7
8
// 下面这些是官方所给的例子
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)

3. Ref作为 shallowReactive 对象的属性值-不会自动解包

如果 ref 作为 shallowReactive 对象的属性,那么不会自动解包

1
2
3
4
5
6
7
8
9
10
11
12
13
<script setup>
import { ref, shallowReactive } from 'vue'

const count = ref(0)
let objReactive = shallowReactive({
  count
})

// RefImpl, 必须使用.value
console.log(objReactive.count)
// 获取到正确的值
console.log(objReactive.count.value)
</script>
1
2
3
<template>
  <h1>{{ objReactive.count.value }}</h1>
</template>

正如上面的例子所示,当Ref作为浅层响应式对象的属性值的情况下,被访问或者修改的时候是不会进行自动解包的。在使用的时候必须加上.value

4. 在模板中的自动解包

在这里顺便说一句哈,上面的例子有一些人可能会存在疑问。可能在模板中访问的时候,会出现不添加.value的情况下也会进行自动解包了。如果你也有同样的疑问请继续往下看,如果没有疑问,那我就帮你增加一个疑问哈哈哈。

首先在模板中,我们只有顶层的ref才会自动解包。什么是顶层的ref呢?简单啰嗦一句:

1
2
// 这就是顶层的ref
const count = ref(0)
1
2
3
4
// 非顶层ref
const test = {
  id: ref(0)
}

然后我们在回到正题中,简单的举个例子:

1
2
3
4
5
import { ref } from 'vue'

const test = {
  id: ref(0)
}
1
2
3
<template>
  <h1>{{ test.id }}</h1>
</template>

看一下我们页面中的渲染情况:
image.png

这看起来好像没有什么问题啊,它好像还是自动解包了啊。不要着急,我们来简单的证明一下;

对上面的模板中,我们进行id+1的操作

1
2
3
<template>
  <h1>{{ test.id + 1 }}</h1>
</template>

你会发现,页面中展示的id出现了很大的变化:

image.png

我相信一些基础很好的朋友已经看出来了问题所在了,对,他给我们进行了类型转换了。他其实一直是一个对象。所以在模板中并没有进行解包。现在就可以解释我们在第四章节开始前的那个疑惑了。

顶层的ref会在模板中自动解包,这就不用我进行举例了吧,我们平时在开发中大家每天都在使用的。