前言
前面两章,给大家讲解了vue3
中ref
, reactive
,readonly
创建响应式数据的API, 以及常用的计算属性computed
, 侦听器watch
,watchEffect
的使用
其中reactive
, ref
, readonly
创建的响应式数据都是深层响应.
而本章主要给大家讲解以上三个API 对应的创建浅层响应式数据的 API, 即shallowRef
, shallowReactive
, shallowReadonly
1. shallowRef
shallowRef
是ref
浅层作用形式。其实就是浅层响应式
shalloRef
的使用方式和ref()
完全相同, 不同的只是vue
对数据响应式处理的不同:
ref
创建的数据, 如果有深层, 比如参数是一个对象, 对象的属性就是深层, 参数对象会被vue
通过reactive
处理为深层响应- 而
shallowRef
创建数据, 只有顶层的value
属性具有响应性, 深层的数据不具有响应性, 会原因返回, 即vue
不会递归的将深层数据通过reactive
处理, 而是原样存储和暴露.
1.1. 类型
我们先看一下shallowRef
API 的类型签名, 其签名如下:
function shallowRef<T>(value: T): ShallowRef<T>
interface ShallowRef<T> {
value: T
}
通过签名可以简单的看出, shallowRef
API 接收一个参数, 返回一个具有value
属性的对象, 且value
属性的类型和参数类型相同.
1.2. ref 和shallowRef 处理原始数据类型
接下会通过示例带大家看一下ref
和shallowRef
在处理原始数据类型的有什么不同.
示例代码:
<template>
<div>
<h3>shallowRef</h3>
<div>{
{
count }}</div>
<div>{
{
count2 }}</div>
<button @click="change">修改数据源</button>
</div>
</template>
<script lang="ts">
import {
defineComponent, ref, shallowRef } from 'vue'
export default defineComponent({
setup() {
const count = ref(0)
const count2 = shallowRef(0)
// 控制台输出 ref, shallowRef 创建的数据
consollog("count", count);
console.log("count2", count2);
// 修改数据
const change = () => {
// count.value++
count2.value++
}
return {
count, count2, change }
}
})
</script>
控制台输出结果
通过代码的运行结果, 你可以看出,
在参数为基本数据类型的情况下, ref
和shallowRef
创建的响应式数据在使用上完全一样, value
属性都具有响应性
通过控制台输出结果, 你会发现ref
和shallowRef
创建的ref
对象极度相似,
如果你阅读过源码, 你就会明白, ref
, shallowRef
返回对象是通过同一个类实例化的对象.因此两个实例对象具有相同的属性. 但是有一个属性__v_isShallow
属性值不同, 因为vue
通过这个属性来区分是ref
还是shallowRef
创建的对象.
这里不对源码实现做过多阐述, 如果你对源码感兴趣, 可以关注我的vue3
源码专栏
1.3. ref 和shallowRef 处理深层对象
ref
和 shallowRef
在处理深层对象就会有所不同:
ref
函数在处理深层对象时, 深层对象会被vue
自动调用reactive
包裹成响应式数据,shallowRef
函数在处理深层对象时,vue
不同将深层对象包裹为响应式对象, 也就是说shallowRef
只有.value
属性值才具有响应性, 深层对象不具有响应性
示例:
<template>
<div>
<h3>shallowRef</h3>