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)