Vue data-driven Simulation Implementation 2. vue Data Simulation Implementation
I. Preface
At the end of the essay "simulating Vue data-driven 1", what if the listener's attribute is an object? Isn't other attributes of this object unable to be listened?
As follows:
If the name and age attributes of a user change, how can we know that they have changed?
Today, we will solve this problem.
By reading the source code of Vue, it is found that it uses the Observer constructor to create an Observer object for each object to listen to data. If the attribute in the data is an object, then we can use the Observer to listen again.
In fact, the core idea is to traverse the tree in sequence (for details about the tree, refer to here ). For example, we can figure out the data in the Demo as follows:
Now, let's take a look at the general idea. Let's create an Observer together.
2. Observer Construction
The overall structure of the Observer is as follows:
Function Observer (data) {// if this is not an Observer object, create an if (! (This instanceof Observer) {return new Observer (data);} this. data = data; this. walk (data);} let p = Observer. prototype = Object. create (null); p. walk = function (data) {/* TODO: listen to all the attributes in data and check whether the attribute values in data are objects. If it is an object, create an Observer instance */} p. convert = function (key, val) {// TODO: Use Object. defineProperty listens to data}
Now, let's complete the walk and convert methods together.
-Walk-
First, we monitor all the attributes of the data object in the walk method, as follows:
p.walk = function(data){ let keys = Object.keys(data); keys.forEach( key => { let val = data[key]; this.convert(key, val); });}
In addition, because attributes may be another object, we need to listen to them.
What should we do?
If it is an object, you can use the Observer constructor again to process it.
As follows:
P. walk = function (data) {let keys = Object. keys (data); keys. forEach (key => {let val = data [key]; // if val is an object, submit it to the Observer for processing if (typeof val = 'object ') {Observer (val);} this. convert (key, val );});}
You may have this question: if you use the Observer to process objects directly, will it not be lost with the parent object?
However, no, because JavaScript is directed to an address relationship for an object, how can it be lost.
-Convert-
For the convert method, it is relatively simple. As always, the Object. defineProperty is used to listen to data, as follows:
P. convert = function (key, val) {Object. defineProperty (this. data, key, {get: () => {console. log (the value of '+ key +' accessed is '+ val); return val ;}, set: (newVal) =>{ console. log ('+ key +' is set to '+ newVal); if (newVal! ==Val) {val = newVal ;}}});}
Now, a simple Observer is constructed. Let's test whether each attribute is successfully monitored.
<script src="./observer.js"></script><script> let data = { user: { name: 'Monkey', age: 24 }, lover: { name: 'Dorie', age: 23 } }; Observer(data);</script>
The effect is as follows:
Perfect. For the complete code, see github.
The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.