JS 数据响应式(三) vue中双向绑定的基础代码

JS 数据响应式(三) vue 双向绑定

实现了vue中双向绑定的简单基础代码,主要是实现了双向绑定的功能,其它不细究
老规矩直接上代码
HTML:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>响应式</title>
  <script src="js/a.js" ></script>
</head>
<body>
  <div  id="app">
{{name}}
<div>{{age}}</div>
<input  v-model="input_text" id="inputID">{{input_text}}//v-model:绑定对应的data下的input_text
  </div>

</body>
<script >
  var vm =  new abc({
        el:"#app",
        _inpuitid:"inputID",
        data:{
          name:"lili",
          age:17,
          input_text:"双绑数据"
        }
    })
   

  </script>
      </html>

JS:

class abc extends EventTarget  //是继承了 EventTarget这个类
{
	 	constructor(obj)
	 	{
			 super()
	 		this.option = obj
	 		this._data = this.option.data;
			 this.el = document.querySelector(this.option.el);
			 this.compileNode(this.el);
			 this.proxydata(this._data);  //这个是调用proxydata
			
		 }
	
	 	compileNode(el){
			let  chile = el.childNodes ;
		
			[...chile].forEach(node=> {	
	
				let text = node.textContent
				let reg = /\{\{\s*([^\s\{\}]+)\s*\}\}/
				let reg1 = /\s*([^\s])s*/
				var sbsj;
				if(node.nodeType===3)
			{
			
				if(reg.test(text))
				{
					let $1 = RegExp.$1;
					
					this._data[$1] && (node.textContent=this._data[$1])
						
					
					this.addEventListener($1,e=>{  //定义一个监听事件,$1监听的对象(字符串),e是参数
						console.info("这是刚才派送过来的监听事件"+e)
						node.textContent=e.detail; //修改文本节点展示的内容
						console.info("进行更改的时候(数据还没完成更改):"+this._data[$1]+",先更改了后面文本节点的展示内容:"+e.detail)
					
					})
					
				}
				

			}
			else if(node.nodeType===1)
			{
				// this.compileNode(node)
			
				
				if(reg.test(text))
				{
					let $1 = RegExp.$1;
				
					if(this._data[$1])
					{
						node.textContent=this._data[$1];
					}
				}
				else if (node.id=="inputID") //判断了一下如果是我要修改的input对象	
				{
					let text1 = node.nextSibling.textContent    //获取这个node下一个节点,的文本信息
					let reg1 = /\{\{\s*([^\s\{\}]+)\s*\}\}/
				
					if(reg1.test(text1))  //匹配对应的正则表达式
				{
					let $1 = RegExp.$1;//赋值匹配的正则表达式第一个值
					
					if(this._data[$1])//如果data包含就为true
					{
						node.value=this._data[$1]; //给对应的节点赋值
						node.addEventListener('input',()=>{     //监听input这个对象
							console.info("输入的时候data数据input_text:"+this._data['input_text'])
							this._data['input_text']=node.value   //把data数据里的input_text属性的值变成node.value(文本输入的值) 修改的是时候触发了proxydata里的Proxy.set函数
							console.info("更改完成:"+this._data['input_text'])
						})
					}
					
				}
				
				}
				
			}
		
			});
			
		 }
		 proxydata(data)
		 {
			let _this= this;
		 this._data=new Proxy(data,{
				 set(obj,prop,newvalue)    
				 {
						//当触发set方法的时候
					 let event = new  CustomEvent(prop,{
						 detail:newvalue   //建立一个自定义事件,名称是修改的数据名称里面的detail赋值为newvalue
					 })
					 console.info("监听过程中,派送了新"+event) 
					 _this.dispatchEvent(event) //把这个新的事件派发出去
					
					return Reflect.set(...arguments);  //返回修改的参数
					
				 }
			 })
			
		 }
}


代码不能顺着看,可以直接复制代码执行一下看看顺序(我都打印出来了).
简单来说,这就是VUE的双向绑定的原理, 用监听事件和proxy 来解决双向绑定
有写的不对的地方或者有更好的写法,请大神们批评指正

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值