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 来解决双向绑定
有写的不对的地方或者有更好的写法,请大神们批评指正