Before vue2, now vuE3, it is vUE. Why vuE3? It must be because vuE3 has a qualitative advantage. This paper analyzes the responsivity principle.

Both are basically publish-subscribe models. A common point is that when data changes, dependencies are triggered to update the data.

Vue2 response principle

Vue2 is implemented primarily through an instance of class new, using Object.defineProperty () to hijack the get and set of individual attributes.

 Object.defineProperty(obj, key, {
            enumerable: true.// Enumerability, indicating whether attributes can be obtained through for-in traversal. The default value is true.
            configurable: false.Configurability controls the modification of the properties it describes, indicating whether the properties of the property can be modified, whether the property can be changed to an accessor property, or whether the property can be redefined by deleting the property via delete. The default value is true.
            get() {
                / / initialization
                // Add an observer to the Dep when the subscriber data changes
                Dep.target && dep.addSub(Dep.target);
                return value;
            },
            set: (newValue) = > {
                this.observer(newValue);
                if(newValue ! == value) { value = newValue; }// Tell Dep to notify the changedep.notify(); }})Copy the code

Acquisition data Display

First the Observer instantiates and gets the data. Traverse data attributes, and defineProperty hijacks each attribute. Get the attribute via get of defineProperty. In addition to getting the property, a dependency action is required to prepare for the data update behavior (i.e. Dep.addsub (dep.target)).

Dep collects dependencies

The dependent collector is implemented using the Dep class. After collecting dependencies, data changes can be implemented to drive page updates. There are two methods to add a dependency and trigger a dependency. In Dep, an empty array is created to hold the dependencies to be collected. AddSub adds a dependency by putting the collected Watcher into an array; The notify dependency notifies Watcher to update, rather than updating itself.

class Dep {
    constructor() {
        this.subs = [];
    }
    addSub(watcher) {
        this.subs.push(watcher);
    }
    notify() {
        this.subs.forEach(item= > item.update())
    }
}
Copy the code
Watcher

There are two main functions: get values and update values. The variables that need to match the binding from the HTML are omitted here. The core of updating a value is assigning a new value to an old value.

class Watcher {
    constructor(vm, expr, cb) {
        this.vm = vm;
        this.expr = expr;
        this.cb = cb;
        this.oldVal = this.getOldVal();
    }
    getOldVal() {
        Dep.target = this;
        const oldVal = compileUtil.getVal(this.expr, this.vm);
        Dep.target = null; // compileUtill class getVal gets the value of a variable
        return oldVal;
    }
    update() {
        const newVal = compileUtil.getVal(this.expr, this.vm);
        if(newVal ! = =this.oldVal) {
            this.cb(newVal); }}}Copy the code

Update data display

Update the set that triggered defineProperty, passing the new value to observer and notifying DEP to update it. In notify, you can call the update operation of watcher to set the new value.

Vue3 response principle

In Vue3, you use Proxy to get and set values. The main core is collecting and triggering dependencies. Take Reactive: IN the notes I also mention the nature of Reactive:

let obj = { name: 'dy'.age: 18 };
let state = new Proxy(obj, {
    get(obj, key) {
        console.log(obj, key); // { name: 'dy', age: 18 } name
        return Reflect.get(obj, key);
    },
    set(obj, key, value) {
        const result = Reflect.set(obj, key, value);
        returnresult; }});Copy the code

The above code shows how the proxy gets and sets values. Here, dependencies are collected when GET and triggered by set, similar to vue2.

This article is participating in the “Nuggets 2021 Spring Recruitment Campaign”, click to see the details of the campaign.