-
分析
- Vue3中最重大的更新之一就是响应式模块reactivity的重写。主要就是用
Proxy
替换`defineProperty 实现响应式;此变化主要是从性能方面考量;
- Vue3中最重大的更新之一就是响应式模块reactivity的重写。主要就是用
-
思路
- 属性拦截的几种方式;
- defineProperty的问题;
- Proxy的优点;
- 其他考量
-
回答范例
- js中做属性拦截常见的方式有三个:
defineProperty
,getter/setter
和Proxy
; - Vue2中使用defineProperty的原因是,当时还没有Proxy,只能用这种方式。由于该APl存在一些局限性,比如对于数组的拦截有问题,为此vue需要专门为数组响应式做一套实现。另外不能拦截那些新增、删除属性,所以就得额外实现$set、$delete;最后defineProperty方案在初始化时就需要深度递归遍历待处理的对象才能对它进行完全拦截,明显增加了初始化的时间;
- 以上两点在Proxy出现之后就可以迎刃而解,不仅可以对数组实现拦截,还能对Map、Set实现拦截;另外Proxy的拦截也是懒处理行为,如果用户没有访问嵌套对象,那么也不会实施拦截,这就让初始化的速度和内存占用都改善了;
- 当然Proxy是有兼容性问题的,IE完全不支持,所以如果需要兼容IE就不能使用vue3;
- js中做属性拦截常见的方式有三个:
-
原理
-
//Proxy属性拦截的原理:利用get、set、deleteProperty实现 function reactive(obj){ return new Proxy(obj,{ get(target,key){}, set(target,key,val){} deleteProperty(target,key){} }) } //Object.defineProperty属性拦截原理:利用get、set实现 function defineReactive(obj,key,val){ Object,defineProperty(obj,key){ get(key){}, set(key,val){} } }