reactive解构最深的一层,失去响应性问题
<script setup lang="ts"> let target = { a: { b: 1 } }; let target1 = { c: 1 }; const obj = reactive(target) const obj1 = reactive(target1) watch(obj, () => { console.log('obj', obj); // 有打印 }) watch(obj1, () => { console.log('obj1', obj); // 无打印 }) let { a } = obj let { c } = obj1 a.b = 3 c = 3 </script>
看看解构后的数据
console.log(a); // Proxy(...)
console.log(c); // 3
由上可以看出,最深一层结构后是数值,所以没有响应性。
使用toRef改写
let { c } = obj1
let c = toRef(obj1, 'c') c.value = 3
或是toRefs
let { c } = toRefs(obj1) c.value = 3
:::补充
reactive原理简易实现
function reactive(params) { return new Proxy(params, { get(target, p, receiver) { if (typeof target[p] === 'object') { reactive(target[p]) } // track(target,p) return Reflect.get(target, p, receiver) }, set(target, p, newValue, receiver) { // trigger(target,key) return Reflect.set(target, p, newValue, receiver) } }) }
reactive对对像属性做了深层代理。
解构原理大致是创建一个变量,从对象中匹配出 与创建变量名相同的 对象属性名,将这个属性的值(或是地址,对象的引用)复制给新的变量。
从reactive和解构原理可以看出,当reactive解构到最后一层,收集依赖的方法是
track(target,p)
,返回值是一个基本数据,此时都是正常的,问题是接下来,
基本数据的值 复制给了一个新的变量,此时,响应被断开。
!!!!!!!!!!!!!!若有不对,请大佬指导!!!!!!!!!!!!!
reactive包裹后的对象 重新赋值失去响应性
Vue2中,data中的对象初始化时,会在组件实例的$data属性上创建(与用户定义的对象名)相同的属性名,....,使用 = 赋值时,是给$data上的对应对象进行赋值