前言
vue3
发布以来经历两年风头正盛,现在大有和react 平分天下的势头,我们知道他是基于proxy 实现响应式的能力, 解决了vue2
所遗留下来的一些问题,同时也正由于proxy的特性,也提高了运行时的性能
凡事有利有弊, proxy
虽然无敌,但是他也有本身的局限,从而产生一些我认为的弊端(其实就是不符合js语言的自然书写方式,有的人觉得就是个特殊写法,他不属于弊端)
- 1、 原始值的响应式系统的实现 导致必须将他包装为一个对象, 通过
.value
的方式访问 - 2、 ES6 解构,不能随意使用。会破坏他的响应式特性
好奇心驱使,研究琢磨了一下,为什么他会造成这两个弊端
原始值的响应式系统的实现
在理解原始值的响应式系统的实现,我们先来温习一下proxy 的能力!
const obj = {name: 'win'
}
const handler = {get: function(target, key){console.log('get--', key)return Reflect.get(...arguments)},set: function(target, key, value){console.log('set--', key, '=', value)return Reflect.set(...arguments)}
}
const data = new Proxy(obj, handler)
data.name = 'ten'
console.log(data.name,'data.name22')
上述代码中,我们发现,proxy 的使用本身就是对于 对象的拦截, 通过new Proxy
的返回值,拦截了obj 对象
如此一来,当你 访问对象中的值的时候,他会触发 get
方法, 当你修改对象中的值的时候 他会触发 set
方法
但是到了原始值的时候,他没有对象啊,咋办呢,new proxy
排不上用场了。
无奈之下,我们只能包装一下了,所以就有了使用.value
访问了
我们来看看具体实现
import { reactive } from "./reactive";
import { trackEffects, triggerEffects } from './effect'
export const isObject = (value) => {return typeof value === 'object' && value !== null
}
// 将对象转化为响应式的
function toReactive(value) {return isObject(value) ? reactive(value) : value
}
class RefImpl {public _value;public dep = new Set; // 依赖收集public __v_isRef &#