Vue双向绑定原理

  • 1、页面–>数据模型层:

     	原理:给元素添加事件监听完成
     	例如给input标签添加input事件来改变value值。
    
  • 2、数据模型层–>页面:

     	原理:通过数据劫持和发布订阅实现
     	数据劫持:拦截数据的变化,常用方案:Object.defineProperty和Proxy
     	Vue2.0 用的是Object.defineProperty
     	Vue3.0 用的是Proxy
    
//数据劫持
<script type="text/javascript">
		var book =[]
		Object.defineProperty(book,'name',{
			//外部给name赋值的时候执行
			set:function(value){
				name=value
				console.log('set你买了一本书'+value)
			},
			//外部获取name值的时候执行
			get:function(){
				console.log('get你的书来啦'+name)
				return '<<'+name+'>>'
			}
		})
		
		book.name="Vue权威指南" //set  这里是赋值,所以会先触发set方法,打印:set你买了一本书Vue权威指南
		console.log(book.name) //这里是获取值,所以会先触发get方法 打印:你的书来啦Vue权威指南
		book.name="Vue权威指南2"//set  这里是赋值,所以会先触发set方法,打印:set你买了一本书Vue权威指南2
		console.log(book.name,'2222') //这里是获取值,所以会先触发get方法 打印:你的书来啦Vue权威指南2
	</script>

打印信息:
在这里插入图片描述

发布订阅示例:
刚刚我们已经实现了数据劫持,那么下面我们要实现的是当数据改变时,要让页面更新。

在这里插入图片描述

<body>
		<input type="" name="" id="inputA" value="" />+
		<input type="" name="" id="inputB" value="" />
		<button type="button" id="btn">=</button>
		<input type="" name="" id="inputC" value="" />
	</body>
我们输入两个数字,让第三个输入框显示两个数之和。输入框A、B它们的数据流向是页面到数据模型
层,那么可以通过监听输入框的onInput事件来更改数据。

那么InputC则可以通过Object.defineProperty的set方法,当valueC被赋值时候,触发刷新
代码如下:
	<body>
		<input type="" name="" id="inputA" value="" />+
		<input type="" name="" id="inputB" value="" />
		<button type="button" id="btn">=</button>
		<input type="" name="" id="inputC" value="" />
	</body>
	<script type="text/javascript">
		var data={
			valueC:''
		}
		//发布订阅
		//订阅器构造函数
		function DingYueQi(){
			this.watchers=[]
		}
		DingYueQi.prototype.addWatcher=function(watcher){
			this.watchers.push(watcher)
		}
		
		DingYueQi.prototype.notifyWatcher=function(value){
			this.watchers.forEach(item=>{
				item.update(value)
			})
		}
		//观察者构造函数
		function Watchers(target){
			this.InputC=target
		}
		Watchers.prototype.update=function(value){
			this.InputC.value=value
		}
		
		//创建一个观察者
		var InputC=new Watchers(document.getElementById('inputC'))
		//创建一个订阅器
		var myDingYue=new DingYueQi()
		myDingYue.addWatcher(InputC)
		
		
		
		//数据劫持(这里只演示valueC)
		Object.defineProperty(data,'valueC',{
			set:function(value){
				valueC=value
				console.log('set')
				myDingYue.notifyWatcher(value)
			},
			get:function(){
				return valueC
			}
		})
		
		
		var inputA=document.getElementById('inputA')
		var inputB=document.getElementById('inputB')
		var btn=document.getElementById('btn')
		
		btn.addEventListener('click',()=>{
			console.log(inputA.value,inputB.value,'544')
			data.valueC=inputA.value*1.0+inputB.value*1.0
			console.log(data.valueC,'44')
		})
		
		
		
	</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

铁牛不是牛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值