Foreword: Recently, the team needed to do a sharing, but I didn’t know how to share it. Finally, I thought that I had always wanted to study the vue source code, and I just "took this opportunity" to study it today.
There are already a lot of articles on Vue data binding on the Internet, but writing it yourself, typing a demo and reading other people's articles are completely different, so...the porters are coming
Currently, there are three main ways to implement data binding:
1. Dirty value check (angular.js) Polling to detect data changes
DOM events, such as users entering text, clicking buttons, etc. . (ng-click)
XHR response event ($http)
Browser Location change event ($location)
Timer event ($timeout, $interval)
Execute $digest() or $apply()
2. Object.defineProperty hijacks the get and set of the object to monitor the data. (vue)
3. Publisher/subscriber mode realizes automatic synchronization of data and views
Advantages of Object.defineProperty
"Dirty value detection"-data changes Finally, a test is performed on the binding relationship between all data and views to identify whether any data has changed. If any changes are processed, it may further cause changes in other data, so this process may cycle several times until it is no longer After data changes occur, the changed data is sent to the view, and the page is updated to display
Object.defineProperty(). Monitor the operations on the data and automatically trigger data synchronization. Moreover, since synchronization is triggered on different data, changes can be accurately sent to the bound view instead of performing a test on all data.
Usage of Object.defineProperty
var a = {}; Object.defineProperty(a, "b", { set: function (newValue) { console.log("我被赋值了!" + newValue); }, get: function () { console.log("我被取值了!"); return 2 } }) a.b = 3; //我被赋值了! console.log(a.b); //我被取值了! //打印 2
As can be seen from the above example, Object.defineProperty passes 3 parameters
The first one: a object
Second one: b attribute in a object
Third one: There are many properties, including useful value, set, get, configurable
Data binding principle :
1. Implement a data listener Observer to monitor all attributes of the data object. If there is any change, get the latest value and notify the dep array
2. Implement an instruction parser Compile, scans and parses the instructions of each element node, replaces the data according to the instruction template
3, implements a dep array, can subscribe to and receive notifications of each attribute change, and execute the corresponding instructions bound Callback function, update view
1. Implement observer
var data = {name: 'beidan'}; observe(data); data.name = 'test'; // 监听到值变化了 beidan 变成 test function observe(data) { if (!data || typeof data !== 'object') { return; } // 取出所有属性遍历 Object.keys(data).forEach(function(key) { defineReactive(data, key, data[key]); }); }
function defineReactive(data, key, val) { Object.defineProperty(data, key, { enumerable: true, // 可枚举 configurable: false, // 不能再define get: function() { return val; }, set: function(newVal) { console.log('监听到值变化了 ', val, ' 变成 ', newVal); val = newVal; } }); }
2. Maintain an array
function Dep() { this.subs = []; } Dep.prototype = { addSub: function (sub) { this.subs.push(sub); }, notify: function (val) { this.subs.forEach(function (sub) { sub.update(val) }); } }; function defineReactive(data, key, val) { Object.defineProperty(data, key, { …… set: function(newVal) { if (val === newVal) return; console.log('监听到值变化了 ', val, ' 变成 ', newVal); val = newVal; dep.notify(val); // 通知所有订阅者 } }); }
3. compile
bindText: function () { var textDOMs = this.el.querySelectorAll('[v-text]'), bindText,_context = this; for (var i = 0; i < textDOMs.length; i++) { bindText = textDOMs[i].getAttribute('v-text'); textDOMs[i].innerHTML = this.data[bindText]; var val = textDOMs[i] var up = function (text) { val.innerText = text } _context.dep.addSub({ value: textDOMs[i], update: up }); } },
The above is the entire content of this article. I hope that the content of this article can bring some help to everyone's study or work. I also hope to support the PHP Chinese website!
For more articles related to brief analysis of vue data binding, please pay attention to the PHP Chinese website!