vue3.0中shallowRef和shallReactive

4,502 阅读1分钟

shallowRef

只处理基础数据类型的响应式,不进行对象类型的响应式。

// 诶,这个它能处理
const count = shallRef(0);

//诶,这个就不能了 为啥呢
const obj = shallRef({name:"Mr.long"})

为什么shallowRef只处理基础数据类型的响应式

我们知道如果给ref传入一个对象的话,那么底层会默认调用reactive函数。返回是一个RefImpl对象。来看源码。

class RefImpl<T> {
  private _rawValue: T

  private _value: T

  public readonly __v_isRef = true
   // 如果_shallow传入是true 那么就是不会调用 toRaw和convert函数 
  constructor(value: T, public readonly _shallow = false) {
    // toRaw 拿到value的原始值
    this._rawValue = _shallow ? value : toRaw(value)
    // 如果传入是一个对象 这里会默认使用 reactive 转成响应式对象
    this._value = _shallow ? value : convert(value)
  }

  get value() {
    track(toRaw(this), TrackOpTypes.GET, 'value')
    return this._value
  }

  set value(newVal) {
    // newVal拿到不是响应式的值...
    newVal = this._shallow ? newVal : toRaw(newVal)
    // 判断传入的值是否发生改变
    if (hasChanged(newVal, this._rawValue)) {
      this._rawValue = newVal
      this._value = this._shallow ? newVal : convert(newVal)

      trigger(toRaw(this), TriggerOpTypes.SET, 'value', newVal)
    }
  }
}

这里可以明显的看到RefImpl类的constructor函数,进行了一个判断,如果_shallow传入是true 那么就是不会调用 toRawconvert函数,拿到的是原值。所以shallowRef函数调用时传入的第二参数为true

shallReactive

只处理对象最外面一层的响应式数据(浅响应式)

const obj = reactive({name:"Mr.long",son:{name:"Mr.liu"}})
// vue不会做son.name响应式