Vue的底层实现双向绑定的原理

Vue的双向数据绑定的底层原理其实是利用原生Js中的Object.defineProperty(对象,“属性名称”,对象) 来通过数据劫持结合发布者-订阅者模式的方式来实现的

 var data = {};
		 
		var temp = {};  //第三方变量 
		
		Object.defineProperty(data,"a",{
			 // value:"abc",
			 // configurable:false  这个属性是决定a的值能否被删除 默认为false
			 // enumerable:false     这个属性是决定a的值能否被遍历
			 // writable:false       这个属性决定a的值能否被 读写改变
			 get(){  //访问a时候触发
				 return temp.a;
			 },
			 //当设置a属性的时候会触发
			 set(value){  //set方法接收input传过来的值并且给temp 
				 temp.a = value;  
			    input.value = value;
			 }
		})
		 
		 input.addEventListener("click",function(){
			data.a = this.value;     
		 })

上面中通过输入框的数据然后赋值给 data.对象中的a属性,因为data通过事件劫持可以知道中间有两个方法 get 和set 一个是 当我们访问data中的a时候触发操作,一个是set 当我们设置data中的a的属性的时候触发, 因此我输入框中输入的值赋值给data中的a时候会触发set方法,set方法的形参接收我的input传过来的值也就是value 此时可以在把value赋值给 temp.a 当输入框中的值发生改变时候我们temp的里面的值会根据输入框中的值会同步变化

.

其实还有一种方法就是Vue3中的proxy
		
		关于Proxy、Reflect是什么?能做什么?以及应用场景有哪些?先都放到一边,我们先来看看使用Proxy如何实现前面得案例需求:
		
		
		 <input type="text" id="demo" name="">
		 <div id="show"></div>
		 <script>
		     const oInput = document.getElementById("demo");
		     const oDiv = document.getElementById("show");
		
		     let oData = {
		         name:"duyi",
		        valueObj:{
		            value:"aaa"
		         }
		    }
		     function upData(){
		         oDiv.innerText = oData.name;
	     }
		    upData();
		     oInput.oninput = function(){
		         proData.name = this.value;
		    }
		   let proData = new Proxy(oData,{
		        set(target,key,value,receiver){
		            Reflect.set(target,key,value);
	            upData();
	         },
		         get(target,key,receiver){
		             return Reflect.get(target,key);
		         }
		    });
		 </script>
		
		通过下面这个示图来了解Proxy、Reflect实现案例需求的流程图:
		

在这里插入图片描述

当oninput事件触发时,proxy代理data接收数据,然后通过reflect映射给data;然后,当有获取Data数据时,Proxy会将get操作拦截下来,再通过reflect映射出data的真实数据。

Proxy在代码量上远远优于Object.defineProperty()的数据劫持操作,并且可以直接作用数组。

Proxy不能直接对引用值属性做深入代理,需要一个节点一个节点的进行创建proxy对象来实现,所以上面的代码如果替换成这样两条与就不能触发数据渲染:

1 oDiv.innerText = oDiv.valueObj.value; //渲染数据
2 proData.valueObj.value = this.value; //修改数据
Proxy是什么?
  Proxy用于修改某些操作的默认行为,同等于在语言层面做出修改,所以属于一种“元编程”,即对编程语言进行编程。

Proxy能做什么?
  Proxy可以理解在目标对象前架设一个拦截层,外界对该对象的访问都必须先通过这层拦截,因此可以提供一种机制对外界的访问进行过滤和改写。Proxy词意为“代理”,所以通常也被称为代理器。

Proxy的应用场景有?
  数据验证、值修正及附加属性、扩展构造函数等,详细可以了解MDN手册:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy

Reflect是什么?
  Reflect词意为“反射”,其对象方法与Proxy对象的方法对应,并且也与Object的方法对应,也就是javaScript用来实现映射的API,注意Reflect不能执行new指令。

  详细可以了解阮一峰的ES6手册:http://es6.ruanyifeng.com/?search=reflect&x=0&y=0#docs/reflect


 set(target,key,value,receiver){
    //value 写入的值
    Reflect.set(target,key,value);
 upData();
 },
get(target,key,receiver){
     // target--属性所属的对象
    // key--属性的名称
     // receiver--代理对象
     // console.log(target,key,receiver);
     return Reflect.get(target,key);
 }

注意Proxy无操作会直接转发代理,可以理解为它内部直接执行了Reflect映射:

let target = {};
let p = new Proxy(target,{});
p.a = 37;
console.log(target.a); //37
关于Proxy和Reflect以后再来补充,毕竟这两个API因为不是语法糖,而是浏览器新拓展的全新功能,转码工具无法进行转码,而浏览器的兼容性目前还很糟糕,还不能得到广泛的应用。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值