Vue3中的reactive与ref

135 阅读2分钟

Vue3的响应性原理,使用的是Proxy,本文主要记录响应性基础的内容,包括reactive与ref.

reactive方法传递的是对象参数,为js对象创建响应式状态,即把对象包裹在响应式代理(Proxy)中,使对象具有响应性.

而对于一个独立的原始值,如果将它变成响应式的,若使用reactive,则需要创建一个对象,该对象包含一个与原始值相同的property,

const reactiveCount=reactive({value:0});
console.log(reactiveCount.value);//reactiveCount的值为:Proxy {value: 0}

另一个简单的方法是使用ref

ref会返回一个响应式对象, 该对象提供一个对内部值的响应式引用, ref对象只包含一个名为value的property,指向该内部值. 如:

const refCount = ref(0)
console.log(refCount);//refCount是一个RefImpl对象

上面refCount是一个RefImpl对象,其值为: image.png

Vue源码中RefImpl对象的定义如下:

image.png

RefImpl对象中定义了value为访问器属性,通过getset方法来读取与设置内部 _value属性的值.

若要获取refCount的数值,需要添加.value

console.log(refCount.value);//输出0
关于ref的自动解包:

当 ref 作为响应式对象(reactive包裹的对象)的 property 被访问或更改时,为使其行为类似于普通 property,它会自动解包内部值 例:

const count=ref(0)
const reactiveData=reactive(count)
console.log(reactiveData.count);//直接返回count的内部值0,而不是RefImpl对象

Ref 解包仅发生在被响应式 Object 嵌套的时候。当从 Array 或原生集合类型如 Map访问 ref 时,不会进行解包:

const books = reactive([ref('Books-first'),ref("Books-second")])
console.log(books);//打印: Proxy {0: RefImpl, 1: RefImpl}
console.log(books[0].value)//books[0]是RefImpl对象,需要.value

当在模板中使用ref创建的值时,ref也会自动解包, 上面的refCount直接在模板中使用时,显示的是0

<template>
  <h1>refCount:{{refCount}}</h1>
</template>

页面显示为 refCount:0