Research on the Principle of vue Bidirectional Data Binding of with demo

  • 2021-07-12 04:53:16
  • OfStack

Yesterday, I was called by my tutor to study the bidirectional data binding principle of vue. . . I thought the principle of things are very advanced, but I didn't expect vue bidirectional binding is really easy to understand. . . I wrote one myself.

Portal

The idea of bidirectional binding

The idea of bidirectional data binding is the synchronization between data layer and UI layer, and when any one of the data changes, it will be updated to the other synchronously.

Some Methods of Bidirectional Binding

At present, there are roughly three methods for the front-end to realize data bidirectional data binding:

1. Publisher-Subscriber Model (backbone. js)

Idea: Use custom data attributes to indicate bindings in HTML code. All bound JavaScript objects and DOM elements will "subscribe" to one publisher object. Whenever a change is detected in an JavaScript object or an HTML input field, we move the proxy event to publisher-subscriber mode, which in turn broadcasts and propagates the change to all bound objects and elements.

2. Detection of stolen goods (angular.js)

Idea: Detect data changes by polling. Only when a specific event is triggered can it enter stolen value detection.

Roughly as follows:

DOM events, such as user entering text, clicking buttons, etc. (ng-click)

XHR Response Event ($http)

Browser Location Change Event ($location)

Timer Events ($timeout, $interval)

· Execute $digest () or $apply ()

3. Data hijacking (vue. js)

Idea: Use Object. defineProperty to monitor the attributes get and set of data objects, and call the instructions of nodes when there are data reading and assignment operations, so that the most common = equal sign assignment can be triggered.

wue Two-way Data Binding Small demo Idea

Construct an Wue object, define its attributes el and data, transmit corresponding data when creating the object, and execute init () method.


var Wue=function(params){
 this.el=document.querySelector(params.el);
 this.data=params.data;
 this.init();
};

html and bindModel are executed in Init method. These two methods are to parse html bound with w-model and w-text instructions in dom, respectively, and make corresponding processing.


init:function(){
  this.bindText();
  this.bindModel();
 }

③ bindText method, which puts the elements with w-text instructions into an array, such as w-text= 'demo', and then makes its innerHTML value equal to the incoming data [demo].


bindText:function(){
  var textDOMs=this.el.querySelectorAll('[w-text]'),
  bindText;
  for(var i=0;i<textDOMs.length;i++){
  bindText=textDOMs[i].getAttribute('w-text');
  textDOMs[i].innerHTML=this.data[bindText];
  }
 }

④ bindModel method, which puts elements with w-model instructions (1 is generally form related elements) into an array, such as w-model= 'demo', and binds keyup events for each element (compatible with browser writing).


bindModel:function(){
 var modelDOMs=this.el.querySelectorAll('[w-model]'),
 bindModel;
 var _that=this;
 for(var i=0;i<modelDOMs.length;i++){
 bindModel=modelDOMs[i].getAttribute('w-model');
 modelDOMs[i].value=this.data[bindModel]||'';
 // Data hijacking 
 this.defineObj(this.data,bindModel);
 if(document.addEventListener){
 modelDOMs[i].addEventListener('keyup',function(event) {
  console.log('test');
  e=event||window.event;
  _that.data[bindModel]=e.target.value;
 },false);
 }else{
 modelDOMs[i].attachEvent('onkeyup',function(event){
  e=event||window.event;
  _that.data[bindModel]=e.target.value; 
 },false);
 }
 } 
}

⑤ Use Object. defineProperty, define set and get methods, and call bindText method in set method. This takes advantage of the fact that the value of w-model is changed in input, and the set method will be automatically executed, so only the method updating w-text can be called in this method.


defineObj:function(obj,prop,value){
  var val=value||'';
  var _that=this;
  try{
  Object.defineProperty(obj,prop,{
  get:function(){
  return val;
  },
  set:function(newVal){
  val=newVal;
  _that.bindText();
  }
  })
 
  }catch (err){
  console.log('Browser not support!')
  } 
 }

⑥ Use


html:<br><h3> Bidirectional data binding demo</h3>
<div id="wrap">
 <input type="text" w-model='demo'>
 <h5 w-text='demo'></h5>
</div><br>js:
 <script src='../js/wue.js'></script>
 <script>
 new Wue({
 el:'#wrap',
 data:{
  demo:'winty'
 }
 })
 </script> 

Complete demo download: https://github.com/LuckyWinty/two-way-data


Related articles: