Vue data-driven Simulation Implementation 4. vue Data Simulation
I. Preface
In "Data Driven by simulation Vue 3", we have extended a $ set method for each object to add attributes, so that we can listen to new attributes.
Of course, arrays are also objects. You can also use the $ set method to add attributes.
However, for arrays, we usually use methods such as push.
PS: In Vue, the push, pop, shift, unshift, splice, sort, and reverse methods are explicit mutations. You can use them to listen for attribute changes and trigger view updates (see here for details)
Next, let's implement the variant methods of these arrays.
Note: The implementation of the Array mutation method is also written in extendObj. js, because arrays are also objects.
II. Implementation of the Array Mutation Method
To implement these mutations, there is no doubt that we will rewrite them. Will they be rewritten in Array. prototype?
Of course not. Does this affect the prototype chain of all array objects!
To avoid this situation, and we just want to inherit these variant array methods on the listening data object, you will find that, in fact, it is similar to implementing the $ set Method in "simulate Vue data drive 3.
First, we create an arrKeys object to save the array method that requires variation and the constant object extendArr, as shown below:
let arrKeys = ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'];const extendArr = [];
Next, the extendArr object listens to the methods in arrKeys one by one. Similar to the $ set method, the overall structure is as follows:
!function(){ arrKeys.forEach(function(key){ proxyObject(extendArr, key, function(){ //TODO }); });}();
Note:The core of the proxyObject method is Object. defineProperty. For details, see "simulate Vue data driver 3 ".
The next step is to implement the core part of the Code. The purpose of rewriting these methods is to listen to data changes. Therefore, we need to rewrite them without changing the original functions of the methods, Array. xxx. apply to implement the original functions.
In addition, the push, unshift, and splice methods can add attributes in the original array. Therefore, we need to listen for new attributes and Their attribute values, here it is exactly the same as the $ set method. Through $ Observer, you can use the observe and convert methods.
The implementation code is as follows:
!function(){ arrKeys.forEach(function(key){ proxyObject(extendArr, key, function(){ console.log('Fun ' + key + ' is observed'); let result; let arrProto = Array.prototype; let ob = this.$Observer; let arr = arrProto.slice.call(arguments); let inserted; let index; switch(key){ case 'push': { inserted = arr; index = this.length; break; } case 'unshift': { inserted = arr; index = 0; break; } case 'splice': { inserted = arr.slice(2); index = arr[0]; break; } } result = arrProto[key].apply(this, arguments); if(inserted){ inserted.forEach(val => { ob.observe(val); ob.convert(index++, val); }); } return result; }); });}();
Finally, the mutations are inherited from the objects to be monitored, as shown below:
// Observer. jsfunction Observer (data) {if (! (This instanceof Observer) {return new Observer (data);} data. _ proto _ = extendObj; // inherits the if (Array. isArray (data) {data. _ proto __. _ proto _ = extendArr;} 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> 'use strict'; let data = { msg: [5, 2, 0], user: { name: 'Monkey', age: 24 }, lover: { name: 'Dorie', age: 23 } }; Observer(data);</script>
The effect is as follows:
Perfect, at this time, you may think that only push, unshift, and splice in the array method will add attributes to the array, so why should we rewrite other methods, such as sort and reverse, I didn't find anything tricky?
Yes, at this time, there is no such thing, but you need to know the sort, reverse and other methods, but it will cause array changes, it will affect the view display, these changes, how to notify the array? This is what will be explained in the next article.
For more information about this article, 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.