This article example shares the specific code of Vue to implement two-way data binding for your reference. The specific content is as follows Arrays and objects in Vue use different binding methods 1. Vue object data binding(1) Data detection In js, we use Object.defineProperty() and ES6 proxy to detect objects In vue2.x, Object.defineProperty() is used to detect data on objects. We first encapsulate Object.defineProperty with the following code: function defineReactive(data, key, val){ if(typeof val === 'object') new Observer(val) let dep = new Dep(); Object.defineProperty(data, key, val) { enumerable: true, configurable: true, get: function () { dep.depend(); return val; }, set: function() { if(val === newVal) { return ; } val = newVal; dep.notify() } } } The only parameters that need to be passed are data, key, and val. Get is triggered whenever data is read from the key in data, and set is triggered whenever data is modified. (2) Dependency collection Collect dependencies first, and when the properties change, trigger the collected dependencies in a loop again. Collect dependencies in getters and trigger dependencies in setters. Dependency class Dep export default class Dep { constructor() { this.subs = [] } addSub() { this.subs.push(sub) } removeSub(sub) { remove(this.subs, sub) } depend() { if(window.target) { this.addSub(window.target) } } notify() { const subs = this.subs.slice() for(let i = 0, l = subs.length; i < l; i++) { subs[i].update() } } } function remove(arr, item) { if (arr.length) { const index = arr.indexOf(item) if(index > -1) { return arr.splice(index, 1) } } } The watcher class is the dependency we collected export default class Watcher { constructor(vm, expOrFn, cb) { this.vm = vm this.getter = parsePath(expOrFn) this.cb = cb this.value = this.get() } get() { window.target = this let value = this.getter.call(this.vm, this.vm) window.target = undefined return value } update() { const oldValue = this.value this.value = this.get() this.cb.call(this.vm, this.value, oldValue) } } (3) Recursively detect all keys (Observer) export class Observer { constructor(value) { this.value = value; if(!Array.isArray(value)) { this.walk(value) } } walk(obj) { const keys = Object.keys(obj) for(let i = 0; i < keys.length; i++) { defineReactive(obj, keys[i], obj[keys[i]]) } } } The Observer class makes all the properties of the object responsive 2.Array change detection(1) Tracking changes in arrays uses interceptors to override prototype methods const arrayProto = Array.prototype export const arrayMethods = Object.create(arrayProto); // The same object as the array prototype as an interceptor ['push','pop','shift','unshift','splice','sort','reverse'].forEach(function (method) { const original = arrayProto[method] Object.defineProperty(arrayMethods, method, { value: function mutator(...args) { return original.apply(this, args) }, enumerable: false, writable: true, configurable: true }) }) The interceptor override prototype has only one sentence value.__proto__ = arrayMethods If there is no __proto__ property, Vue will mount these arrayMethods to the detected array Arrays are similar to objects in that they collect dependencies in getters, while array-triggered dependencies are in interceptors. The array's dependencies are stored on the Observer instance and must be accessible to both getters and interceptors. __ob__ is a non-enumerable attribute, the value of this attribute is the current Observer instance Save the Dep instance in the Observer attribute. If the value already has an __ob__ attribute, there is no need to create an Observer instance again to avoid repeated detection of value changes. Send notifications like array dependencies this.__ob__.dep.notify(); (2) Specific methods for detecting data changes Loop through each item in the array and execute the observe function to detect changes observeArray(items) { for(let i = 0; l = items.length; i < l; i++) { observe(items[i]); } } Arrays need to detect new elements By intercepting push, unshift, splice and other methods, and storing args in inserted if(inserted) ob.observeArray(inserted) Summarize:Array tracks changes differently than Object does, so we create an interceptor to overwrite the array prototype to track changes. In order not to pollute the global Array.prototype, we only use __proto__ in Observer to overwrite the prototype for the array that needs to detect changes. Array collects dependencies in the same way as Object, which is collected in getters, triggered in interceptors, and dependencies are stored on Observer instances. On the Observer, we mark each detected data with __ob__ and save this(Observer) on __ob__. This is mainly to ensure that the same data is only detected once. In addition, we can easily get the dependencies saved on the Observer instance through __ob__. The array needs to loop to make each array item responsive. When a new element is added to the array, we extract the parameters and then use observeArray to detect changes in the new data. For arrays, only prototype methods can be intercepted, and some unique methods cannot be intercepted. The above is the full content of this article. I hope it will be helpful for everyone’s study. I also hope that everyone will support 123WORDPRESS.COM. You may also be interested in:
|
<<: In-depth analysis of JDBC and MySQL temporary tablespace
>>: What command is better for fuzzy searching files in Linux?
Table of contents pom configuration Setting.xml c...
1. Download address https://dev.mysql.com/downloa...
Preface Recently, I added two fields to a table i...
Table of contents 1 Java environment configuratio...
This article example shares the specific code of ...
engine Introduction Innodb engine The Innodb engi...
JavaScript to achieve the source code download ad...
The core is mysqldump and Runtime The operation i...
Without further ado, here are the renderings. The...
Preface I am used to writing less/sass, but now I...
1. Elements and tags in HTML <br />An eleme...
The specific code for JavaScript to implement the...
html , address , blockquote , body , dd , div , d...
To install VMWare under Linux, you need to downlo...
Installing XML extension in PHP Linux 1. Enter th...