Proxy

Proxy从ES6到VUE3.0

ES6-Proxy代理
Vue3.0-Proxy
感兴趣的可以去看一下,我这里只记录一下我面试遇到的
vue双向绑定的原理 v-module
vue数据双向绑定通过‘数据劫持’:指的是在访问或者修改对象的某个 属性时,通过一段代码拦截这个行为,进行额外的操作或者修改返回结 果 。 vue2.0用 Object.defineProperty() 这个方法重新定义了对象 获取属性值(get)和设置属性值(set)的操作来实现的
vue3.0用Proxy

  • 订阅发布模式实现
    首先要对数据进行劫持监听,所以我们需要设置一个监听器Observer,用来监听所有属性。如果属性发上变化了,就需要告诉订阅者Watcher看是否需要更新。
    因为订阅者是有很多个,所以我们需要有一个消息订阅器Dep来专门收集这些订阅者,然后在监听器Observer和订阅者Watcher之间进行统一管理的。
    接着,我们还需要有一个指令解析器Compile,对每个节点元素进行扫描和解析,将相关指令(如v-model,v-on)对应初始化成一个订阅者Watcher,
    并替换模板数据或者绑定相应的函数,此时当订阅者Watcher接收到相应属性的变化,就会执行对应的更新函数,从而更新视图
function type(name){  
	this.name = name;
	this.readers = [];//定义一个容器,来放谁订阅了
			
	this.subscription = function(p){
		this.readers.push(p);
	}
        this.unsubscribe= function(p) {
	let index = this.readers.findIndex(person=>{
		return person == p;
       })
	this.readers.splice(index,1);//移除这个人
      }
			
	this.publish = function(){//遍历这个数组,给每个人发消息
	this.readers.forEach(p => {
		p.notice(this.name+"的新消息"+Math.random());
	})
	}
 }
		
    function Person(name) {//实例对象人的构造函数
		this.name = name;//获取人的名字
		this.notice = function(msg){//注意有消息过来了
		console.log(this.name+ "收到了 "+ msg);
			}
		}
		
	let event = new type("抖音");
		
		
		
	let zhangsan = new Person("zhangsan");
	let lisi = new Person("lisi");
	let wangwu = new Person("wangwu");

		
	event.subscription(wangwu)//王五订阅
	 event.subscription(lisi)//李四订阅
	event.unsubscribe(lisi)//李四退订
	event.publish();//公布

Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该 对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对 外界的访问进行过滤和改写。
proxy
如果需要实现一个 Vue 中的响应式,需要我们在 get 中收集依赖,在 set 派发更新,之所以 Vue3.0 要使用 Proxy 替换原本的 API 原因在 于 Proxy 无需一层层递归为每个属性添加代理,一次即可完成以上操 作,性能上更好,并且原本的实现有一些数据更新不能监听到,但是 Proxy 可以完美监听到任何方式的数据改变,唯一缺陷可能就是浏览器 的兼容性不好了

  let obj = { a: 1 };
  let getLogger = (target, key) => {
    console.log(`'${key}' = ${target[key]}`);
  };
  let setBind = (value, key) => {
    console.log(`监听到属性${key}改变为${value}`);
  };

  let handler = {
    get(target, key, value) {
      getLogger(target, key);
      return Reflect.get(target, key, value);
    },
    set(target, key, value, receiver) {
      setBind(value, key);
      return Reflect.set(target, key, value);
    }
  };
  let proxy = new Proxy(obj, handler);
  proxy.a = 2;
  console.log(proxy.a);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值