2024-03-24
vue
00
请注意,本文编写于 176 天前,最后修改于 176 天前,其中某些信息可能已经过时。

目录

ref 和 reactive 的区别
应用场景和源码解读
应用场景
源码解读
总结
ref 和 reactive 的区别
应用场景和源码解读
应用场景
源码解读
总结

在Vue 3中,refreactive 是两种响应式数据引用的方式,它们有不同的特点和适用场景。

refreactive 的区别

  1. ref

    • ref 是用来创建一个包装对象(wrapper object)的引用,它会将基本数据类型(如数字、字符串等)转换成一个可响应的对象。在创建 ref 时,会返回一个带有 value 属性的对象。
    • 使用 ref 创建的对象是具有 value 属性的对象,操作时需要通过 .value 来访问其真实的值。
    • 适用于管理单一值的状态,比如数字、字符串等简单类型的状态。
  2. reactive

    • reactive 是用来创建一个可响应的对象引用。它将整个对象转换成可响应的对象,对象的属性都会变成响应式的。
    • 使用 reactive 创建的对象本身就是一个响应式对象,不需要额外的 .value 属性来访问其值。
    • 适用于管理复杂的对象状态,比如包含多个属性的对象或数组等。

应用场景和源码解读

应用场景

  • 使用 ref 适合管理简单的数据,比如管理一个数字、字符串等。
  • 使用 reactive 适合管理复杂的数据,比如一个对象包含多个属性的对象或者数组。

源码解读

  1. ref 的源码解读
javascript
export function ref(value) { return createRef(value) } function createRef(value, shallow = false) { // 创建一个代理对象,value 存在在 inner 中 const r = { _v_isRef: true, get value() { track(r, TrackOpTypes.GET, 'value') return shallow ? value : _shallowRef(value) }, set value(newVal) { if (hasChanged(toRaw(newVal), value)) { value = shallow ? newVal : convert(newVal) trigger(r, TriggerOpTypes.SET, 'value', __DEV__ ? { newValue: newVal } : void 0) } } } return r }

以上代码简要解读如下:

  • ref 函数内部调了 createRef,并传入初始值 value
  • createRef 内部创建了一个带有 _v_isRef 标志和 value 存取器属性的对象。
  • value 存取器属性内部用了 track 方法进行追踪,并在设置新值时触发 trigger
  1. reactive 的源码解读
javascript
export function reactive(target) { if (readonlyToRaw.has(target) || reactiveToRaw.has(target)) { return target } return createReactiveObject( target, mutableHandlers, mutableCollectionHandlers ) } function createReactiveObject(target, baseHandlers, collectionHandlers) { // ... 省略部分代码 const observed = new Proxy(target, collectionTypes.has(target) ? collectionHandlers : baseHandlers) return observed }

以上代码简要解读如下:

  • reactive 函数内部创建了一个代理对象 observed,并返回这个代理对象。
  • 代理对象在根据目标对象的类型用不同的 Handler 处理时,在改变代理对象的值时,会触发相应的响应式操作。

总结

  • ref 适用于管理简单的数据,返回的对象具有 .value 属性。
  • reactive 适用于管理复杂的对象状态,返回的对象本身就是具有响应性的。
  • 在源码层面,refreactive 的实现分基于 createRefcreateReactiveObject 函数,通过 Proxy 对象进行了响应式的处理。当然,让我来替换一下原文中的特殊字符。请稍等片刻。在Vue 3中,refreactive 是两种响应式数据引用的方式,它们有不同的特点和适用场景。

refreactive 的区别

  1. ref

    • ref 是用来创建一个包装对象(wrapper object)的引用,它会将基本数据类型(如数字、字符串等)转换成一个可响应的对象。在创建 ref 时,会返回一个带有 value 属性的对象。
    • 使用 ref 创建的对象是具有 value 属性的对象,操作时需要通过 .value 来访问其真实的值。
    • 适用于管理单一值的状态,比如数字、字符串等简单类型的状态。
  2. reactive

    • reactive 是用来创建一个可响应的对象引用。它将整个对象转换成可响应的对象,对象的属性都会变成响应式的。
    • 使用 reactive 创建的对象本身就是一个响应式对象,不需要额外的 .value 属性来访问其值。
    • 适用于管理复杂的对象状态,比如包含多个属性的对象或数组等。

应用场景和源码解读

应用场景

  • 使用 ref 适合管理简单的数据,比如管理一个数字、字符串等。
  • 使用 reactive 适合管理复杂的数据,比如一个包含多个属性的对象或者数组。

源码解读

  1. ref 的源码解读
javascript
export function ref(value) { return createRef(value) } function createRef(value, shallow = false) { // 创建一个代理对象,value 存在在 inner 中 const r = { _v_isRef: true, get value() { track(r, TrackOpTypes.GET, 'value') return shallow ? value : _shallowRef(value) }, set value(newVal) { if (hasChanged(toRaw(newVal), value)) { value = shallow ? newVal : convert(newVal) trigger(r, TriggerOpTypes.SET, 'value', __DEV__ ? { newValue: newVal } : void 0) } } } return r }

以上代码简要解读如下:

  • ref 函数内部调了 createRef,并传入初始值 value
  • createRef 内部创建了一个带有 _v_isRef 标志和 value 存取器属性的对象。
  • value 存取器属性内部用了 track 方法进行追踪,并在设置新值时触发 trigger
  1. reactive 的源码解读
javascript
export function reactive(target) { if (readonlyToRaw.has(target) || reactiveToRaw.has(target)) { return target } return createReactiveObject( target, mutableHandlers, mutableCollectionHandlers ) } function createReactiveObject(target, baseHandlers, collectionHandlers) { // ... 省略部分代码 const observed = new Proxy(target, collectionTypes.has(target) ? collectionHandlers : baseHandlers) return observed }

以上代码简要解读如下:

  • reactive 函数内部创建了一个代理对象 observed,并返回这个代理对象。
  • 代理对象部分根据目标对象的类型采用不同的 Handler 处理。
  • 在改变代理对象的值时,会触发相应的响应式操作。

总结

  • ref 适用于管理简单的数据,返回的对象具有 .value 属性。
  • reactive 适用于管理复杂的对象状态,返回的对象本身就是具有响应性的。
  • 在代码层面,refreactive 的实现分基于 createRefcreateReactiveObject 函数,通过 Proxy 对象进行了响应式的处理。
如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:姚文罡

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!