Disadvantages of Vue2.0 bidirectional binding
The data response of Vue2.0 is a combination of data hijacking and publiser-subscriber mode, using object.defineProperty () to hijack the setter and getter of each attribute, but it is not a perfect solution to achieve data responsiveness. In some cases, it needs to be patched or hacked, which is also its defect, mainly manifested in two aspects:
- After a VUE instance is created, new or deleted object attributes cannot be detected, only if the data has been modified
- Cannot listen for array changes
Resolution:
-
After a Vue instance is created, there is no way to detect additions or deletions of Object attributes, only to trace whether data has been modified (Object.defineProperty can only hijack Object attributes).
When a Vue instance is created, all DOM objects are iterated over and get and set are added for each data attribute. Get and set allow Vue to observe changes to data and trigger updates. However, if you add (or remove) a property after Vue instantiation, the property will not be processed by Vue, changing get and set.
Solution:
Vue.set(obj, propertName/index, value) // Add a new attribute to the child of a responsive object, which can be reassigned data.location = { x: 100.y: 100} data.location = {... data,z: 100} Copy the code
-
Cannot listen for array changes
Vue in the implementation of the array response type, it USES some hack, can’t be monitored array by rewriting the condition of the array part ways to implement reactive, that will only limit in the array of push/pop/shift/unshift/splice/sort/reverse seven methods, Other array methods and array uses are not detected, such as the following two uses
vm.items[index] = newValue; vm.items.length Copy the code
Vue implements array responsive methods
Array.prototype (array.prototype) {array.prototype (array.prototype) {array.prototype (array.prototype) {array.prototype (array.prototype) {array.prototype (array.prototype) {array.prototype (array.prototype);
const methods = ['pop'.'shift'.'unshift'.'sort'.'reverse'.'splice'.'push']; // Copy array. prototype and point its prototype to array. prototype let proto = Object.create(Array.prototype); methods.forEach(method= > { proto[method] = function () { // Override the array method in proto Array.prototype[method].call(this. arguments); viewRender()// View update function observe(obj) { if (Array.isArray(obj)) { // Array implementation is reactive obj.__proto__ = proto; // Change the array prototype passed in return; } if (typeof obj === 'object') {...// A responsive implementation of the object}}}})Copy the code