shallowRef与ref的原理浅析

vue3中的shallowRef与ref是怎么实现的呢?学习自尚硅谷

目的

使一个正常的js基本类型转化为响应式对象,能够对get和set数据的时候进行拦截

解决方案

简单的说,如果值为基本类型,不是object,那么在内存中创建一个新变量 _value(也可以说是复制), 在获取和改动的时候(set)对这个值进行修改和获取,这样就可以做到对get和set的时候进行拦截。如果是object类型,参见我前面一篇文章https://www.cnblogs.com/lyzz1314/p/14810559.html,进行reactive华处理。

严格来讲,这个最后结果还不是响应式对象,只是这个object再增删改查属性的时候会触发自定义逻辑,具体编写什么样的逻辑能能够做到vue3中的响应式,本文没有阐述。

/*
自定义shallowRef
*/
function shallowRef(target) {
  const result = {
    _value: target, // 用来保存数据的内部属性
    _is_ref: true, // 用来标识是ref对象
    get value () {
      return this._value
    },
    set value (val) {
      this._value = val
      console.log('set value 数据已更新, 去更新界面')
    }
  }

  return result
}

/* 
自定义ref
*/
function ref(target) {
  if (target && typeof target==='object') {
    target = reactive(target)
  }

  const result = {
    _value: target, // 用来保存数据的内部属性
    _is_ref: true, // 用来标识是ref对象
    get value () {
      return this._value
    },
    set value (val) {
      this._value = val
      console.log('set value 数据已更新, 去更新界面')
    }
  }

  return result
}

/* 测试自定义shallowRef */
const ref3 = shallowRef({
  a: 'abc',
})
ref3.value = 'xxx'
ref3.value.a = 'yyy'


/* 测试自定义ref */
const ref1 = ref(0)
const ref2 = ref({
  a: 'abc',
  b: [{x: 1}],
  c: {x: [11]},
})
ref1.value++
ref2.value.b[0].x++
console.log(ref1, ref2)
posted @ 2021-05-25 21:09  Bravo_Jack  阅读(1604)  评论(0编辑  收藏  举报