1. How do I track changes? Anyone who writes vUE at all now knows that Object. DefineProperty was used in 2.0

function defineReactive(obj, key, val) { Object.defineProperty(obj, key, { enumerable: true, configurable: true, get: function reactiveGetter() { return val; }, set: function reactiveSetter(newVal) { if (newVal === val) { return; } val = newVal; }})}Copy the code

2. If there is an instance that uses the current object, it will be collected into the current dependency

function defineReactive(obj, key, val) { let dep = []; Object.defineProperty(obj, key, { enumerable: true, configurable: true, get: function reactiveGetter() { dep.push(this.$vm); return val; }, set: function reactiveSetter(newVal) { if (newVal === val) { return; } // something triggers the current dep for(let I = 0; i < dep.length; i++) { dep[i].notify(); } val = newVal; }})}Copy the code

3. When we think about this, we can see that we’re just thinking about the simplest case, something like this

export default {  
    data () {    
        return {      
            a: 1,      
            b: '1'    
        }  
    }
}
Copy the code

4. What if the A attribute is also an object

class Observe {  
    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]]);    
        }  
    }
}
function defineReactive(obj, key, val) {  
    if (typeof obj[key] === 'object') {    
          new Observe(val);  
    }  
    let dep = [];  
    Object.defineProperty(obj, key, {    
        enumerable: true,    
        configurable: true,    
        get: function reactiveGetter() {      
            dep.push(this.$vm);      
            return val;    
        },    
        set: function reactiveSetter(newVal) {      
            if (newVal === val) {        
                return;      
            }      
            // 某种触发当前的dep                 
            for(let i = 0;i < dep.length;i++) {        
                dep[i].notify(); 
                // 假设notify是可以让对应实例重新渲染的函数      
            }      
            val = newVal;    
        }  
    }
)}
Copy the code

5. To summarize

The purpose of responsiveness is to render and update the page immediately when the data changes; In Vue2.0, the Object. DefineProperty is used to convert the reading and updating of properties into getters and setters to track changes. When reading data, it goes to the getter and when changing data, it goes to the setter. The purpose of the Observer is to set all properties of an object to be responsive. Each property has its own set of dependencies, called DEP. When data is read by multiple instances, these instances are pushed into the set. When data changes, the DEP is looped through in the setter to inform all instances of updates in turn

6. Note

$set = $set = $set = $set = $set = $set = $set = $set = $set = $set