Vue data-driven Simulation Implementation 3. vue Data Simulation Implementation
I. Preface
In "data Driven by simulation Vue 2", we implemented an Observer constructor that can be used to listen to all the attributes of existing data.
But what if we want to add a property to an object?
As follows:
Then, the newly added infor attribute and its object attribute are not monitored.
What should I do now?
By reading the source code of Vue, it is found that it is implemented by adding the attribute method $ set.
That is to say, if we use the conventional method to add an attribute to an object (as shown above), we cannot know and monitor it. Therefore, we extend a $ set method for each object to use an additional attribute, as follows:
Data. user. $ set ('infor ', {msg: 'Happy '});
Now, let's implement the $ set method together.
II. Implementation of the $ set Method
First, we need to create a constant extendObj object to bind the $ set method to it.
You may wonder why we need an extendObj object? Just assign the $ set function to each object that needs to be listened on. Isn't that all done?
Yes, that's fine, but as demand grows, what if we want to extend other methods for each listener object? Is it necessary to assign values to objects in Observer?
So, create a constant extendObj object, as follows:
Const extendObj = {};
Because we bind $ set to extendObj and make $ set unenumerative, we will use Object. defineProperty to extract it as follows:
function proxyObject(obj, key, val, enume){ Object.defineProperty(obj, key, { value: val, enumerable: !!enume, writable: true, configurable: true }); };
The next step is to implement the $ set method. The overall structure is as follows:
ProxyObject (extendObj, '$ set', function (key, val) {// this points to extendObj if (this. hasOwnProperty (key) {return;} else {/* TODO: Listen to the key attribute in extendObj. If the key attribute value is an object, listen to the key attribute value again */}});
See the above TODO comments, whether it is familiar, not just in the "simulation of Vue data driver 2" met, through the Observer. prototype. convert listens to the key attribute. It is not enough to listen to the key attribute value again through new Observer.
Indeed, once this is done, it will not be the same as the above-mentioned problem of "directly assigning $ set to the listener object". The coupling is too large and it is difficult to maintain as demand increases.
To fix this issue, you need to add a $ observer attribute to each listener in the Observer module. The value points to the Observer instance, as shown below:
// Observer. jsp. walk = function (data) {let keys = Object. keys (data); keys. forEach (key => {let val = data [key]; if (typeof val = 'object') {new Observer (val);} this. convert (key, val) ;}); // $ the Observer attribute points to the data of the Observer instance. $ Observer = this;} // Add an observe Method p. observe = function (data) {if (typeof data = 'object') {new Observer (data );}}
Now, the overall implementation of $ set is as follows:
proxyObject(extendObj, '$set', function(key, val){ if(this.hasOwnProperty(key)){ return; }else{ proxyObject(this, key, val, true); let ob = this.$Observer; ob.observe(val); ob.convert(key, val); } });
At this point, a simple $ set method has been built.
As we mentioned above, a constant extendObj object is needed for better code management. So far, the $ set method has not been extended on the objects to be monitored. The following is to achieve the above effect:
// Observer. jsfunction Observer (data) {if (! (This instanceof Observer) {return new Observer (data) ;}// point the Hidden Pointer of the listener object to our extendObj object data. _ proto _ = extendObj; this. data = data; this. walk (data );}
Okay, everything is done. Next, let's test it:
<script src="./extendObj.js"></script><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.