Proxy实现监听

之前分享过vue2的响应式,然后有人问vue3用proxy是怎么实现的,本来打算研究一波,看了源码之后,发现自己想多了,所以改成学一学proxy的使用。 想看源码的可以去git上面下载: https://github.com/vuejs/vue-next 然后主要代码是在这两个目录下,而且都是用ts写的: packages/reactivity下面的reactive和baseHandlers Proxy之前有稍微过一遍,在ES6目录里面,支持13种拦截。然后返回对象的值使用了Reflext,主要是为了将Object对象一些明显属于语言内部的方法放到Reflect对象上。之前也有过一遍。 然后大概简单使用: let obj = { msg: { a: 10 }, arr: [1, 2, 3] } let handler = { get(target, key){ console.log('get', target, key); //懒监听,去获取的时候才监听对象里面的对象,而不是直接递归循环监听 if(typeof target[key] === 'object' && target[key] !== null){ return new Proxy(target[key], handler); } return Reflect.get(target, key); }, set(target, key, value){ console.log('set', target, key, value); //数组新增会执行两次,一次是修改length,一次是添加值 let oldValue = target[key]; if(!oldValue){ //找不到老值,新增 }else if(oldValue !== value){ //老值和新值不相等,修改 } return Reflect.set(target, key, value); } } let proxy = new Proxy(obj, handler) proxy.arr.push(4); proxy.msg.a = 50; proxy.msg.b = 60; proxy.c = 70; 相比较起来,defineProperty无法一次性监听所有属性,必须遍历或者递归,而且无法监听新增的属性。对于数组,defineProperty需要劫持数组方法,进行函数劫持。对于上面的问题,Proxy都支持。运行上面的方法,可以试试是不是都可以。 Proxy拦截的还很多,要不是兼容性问题,我觉得defineProperty会被取代。Proxy能做的还有很多,不过平常是用不上了,要是开发一些工具库绝对是很好的选择。 image

本文章由javascript技术分享原创和收集

发表评论 (审核通过后显示评论):