介绍
这篇文章将为大家详细讲解有关Vue 2.0中实现双向绑定的原理是什么,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。
<强> 1,定义构造函数强>
function Vue(选项){ 这。el 美元;=,document.querySelector (option.el);,//获取挂载节点 这。data 美元;=,option.data; 这。methods 美元;=,option.methods;=,this.deps ,{},,//所有订阅者集合,目标格式(一对多的关系):{味精:[订阅者1,订阅者2,订阅者3],,信息:,(订阅者1,订阅者2]} ,this.observer (。$ data);,//调用观察者 ,this.compile(这一点。el美元);,//调用指令解析器 }
<强> 2,定义指令解析器强>
Vue.prototype.compile =, function (el), { ,let nodes =, el.children;,//获取挂载节点的子节点 ,for (var 小姐:=,0;,小姐:& lt;, nodes.length;,我+ +),{ 节点,var node =,(我); ,if (node.children.length), { ,this.compile(节点),//递归获取子节点 ,} ,if (node.hasAttribute (& # 39; l-model& # 39;)),{,//当子节点存在l型指令 ,let attrVal =, node.getAttribute (& # 39; l-model& # 39;);,//获取属性值 ,node.addEventListener(& # 39;输入# 39;,,((),=祝辞,{ ,this.deps [attrVal] .push (new 观察者(节点,“value",,这个,,attrVal)),,//添加一个订阅者=,let thisNode 节点; ,return (),=祝辞,{ 这才能。$ data [attrVal],=, thisNode.value //更新数据层的数据 ,} ,})()) ,} ,if (node.hasAttribute (& # 39; l-html& # 39;)), { ,let attrVal =, node.getAttribute (& # 39; l-html& # 39;);,//获取属性值 ,this.deps [attrVal] .push (new 观察者(节点,“innerHTML",,这个,,attrVal)),,//添加一个订阅者 ,} ,if (node.innerHTML.match (/{{((^ \ {| \}] +)}}/)), { ,let attrVal =, node.innerHTML.replace (/[{{|}}]/g, & # 39; & # 39;);,//获取插值表达式内容 ,this.deps [attrVal] .push (new 观察者(节点,“innerHTML",,这个,,attrVal)),,//添加一个订阅者 ,} ,if (node.hasAttribute (& # 39; l:点击# 39;)),{ ,let attrVal =, node.getAttribute (& # 39; l:点击# 39;);,//获取事件触发的方法名 ,node.addEventListener(& # 39;点击# 39;,,这个。方法[attrVal] .bind美元($ data)),,//将这指向元数据 ,} ,} }
<强> 3,定义观察者强>
Vue.prototype.observer =,功能(数据){ ,(var key 拷贝数据){ ,(函数(){ ,let val =,数据(关键);,//每一个数据的属性值 ,that.deps(例子),=,[];,//初始化所有订阅者对象{味精:[订阅者),,信息:,[]} ,var watchers =, that.deps(例子); ,Object.defineProperty(数据,键,,{,//数据劫持 ,得到:函数(){ return 才能,val; }, ,集:函数(newVal){,//设置值(说明有数据更新) 如果才能(val !==, newVal) { 时间=val 才能;newVal; ,,}//,才能通知订阅者 watchers.forEach才能(观察家=祝辞{ watcher.update才能() })才能 ,} ,}) ,})(本) ,} }
<强> 4,定义订阅者强>
function 观察者(attr, el,还以为,vm, attrVal), {=,this.el el;=,,this.attr  attr;=,this.vm 虚拟机;=,,this.val  attrVal; ,this.update();,//更新视图 }
<强> 5,更新视图强>
Watcher.prototype.update =, function (), { ,this.el [this.attr],=this.vm。$ data [this.val] }
以上代码定义在一个Vue。js文件中,在需要使用双向绑定的地方引入即可。
尝试使用一下:
& lt; ! DOCTYPE html> & lt; html  lang=癳n"祝辞 & lt; head> ,& lt; meta charset=癠TF-8"比; ,& lt; meta name=皏iewport",内容=翱矶?设备宽度,初始=1.0,比; ,& lt; meta  http-equiv=癤-UA-Compatible",内容=癷e=edge"比; ,& lt; title> Document ,& lt; script  src=啊?vue.js"祝辞& lt;/script> & lt;/head> & lt; body> & lt; ! ,实现mvvm的双向绑定,是采用数据劫持结合发布者——订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,吸气,在数据变动时发布消息给订阅者,触发相应的监听回调。就必须要实现以下几点: ,1,实现一个数据监听器观察者,能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者 ,2,实现一个指令解析器编译、对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数 ,3,实现一个观察者,作为连接观察者和编译的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图 ,4,mvvm入口函数,整合以上三者 ,——比; ,& lt; div id=癮pp"比; ,& lt; input 类型=皌ext", l型=癿sg",在 ,& lt; p  l-html=癿sg"祝辞& lt;/p> ,& lt; input 类型=皌ext", l型=癷nfo",在 ,& lt; p  l-html=癷nfo"祝辞& lt;/p> ,& lt; button l:点击=癱lickMe"在点我& lt;/button> ,& lt; p>{{味精}}& lt;/p> ,& lt;/div> null null null null null null null null null null null null null null null nullVue 2.0中实现双向绑定的原理是什么