reactivereactive是一种在Vue3中实现响应式数据的方法。在Vue2中,响应式数据是通过defineProperty来实现的。在Vue3中,响应式数据是通过ES6Proxy实现的,响应式参数必须是对象(json/arr)。如果传递其他对象给reactive,默认会修改对象,不会自动更新界面。如果要更新,可以重新赋值。这里我们使用Reflect来实现Reflect对象和ProxyLike对象,它也是ES6提供的一种新的操作对象的API。Reflect对象的设计目的(1)将Object对象的一些明显属于语言内部的方法(如Object.defineProperty)放在Reflect对象上。现阶段一些方法同时部署在Object和Reflect对象上,以后新的方法只会部署在Reflect对象上。也就是说,可以从Reflect对象中获取语言的内部方法。(2)修改部分Object方法的返回结果,使其更合理。例如,Object.defineProperty(obj,name,desc)会在无法定义属性时抛出错误,而Reflect.defineProperty(obj,name,desc)会返回false。(3)将对象操作转化为功能行为。某些Object操作是命令式的,比如nameinobj和deleteobj[name],而Reflect.has(obj,name)和Reflect.deleteProperty(obj,name)将它们转化为功能行为。(4)Reflect对象的方法与Proxy对象的方法一一对应。只要是Proxy对象的方法,在Reflect对象上都能找到对应的方法。这使得Proxy对象可以方便地调用相应的Reflect方法来完成默认行为,作为修改行为的依据。也就是说,无论Proxy如何修改默认行为,你总能在Reflect上得到默认行为。阮一峰ES6有介绍代码实际constisObject=(val)=>val!==null&&typeofval==="object";constconvert=(target)=>(isObject(target)?reactive(target):target);consthasOwnProperty=Object.prototype.hasOwnProperty;consthasOwn=(target,key)=>hasOwnProperty.call(target,key);exportfunctionreactive(target){if(!isObject(target))返回目标;consthandler={get(target,key,receiver){//收集依赖console.log("get",key);constresult=Reflect.get(target,key,receiver);返回转换(结果);},set(target,key,value,receiver){constoldValue=Reflect.get(target,key,receiver);让结果=真;if(oldValue!==value){result=Reflect.set(target,key,value,receiver);//触摸更新console.log("set",key,value);}返回结果;},deleteProperty(target,key){consthadKey=hasOwn(target,key);骗局stresult=Reflect.deleteProperty(target,key);if(hadKey&&result){//触发更新console.log("delete",key);}返回结果;},};returnnewProxy(target,handler);}测试代码
