Design JS source code analysis repository to achieve │ easy mvvm

Author: Knife brother (Zhu)

Preface: mvvm mode that is model-view-viewmodel mode for short, to achieve single / two-way data binding, so that the front end developers from the complex out of the dom event, the linkage between process data easily and ui. This paper will start with vue two-way data binding, analysis of the core code and ideas mvvm library design.

1, the demand for collation and analysis

demand:

  • Once the data ui update data corresponding to the change

  • ui ui to change the trigger event to change the corresponding data

analysis:

  • Refreshing function instruction acquired by dom node for refreshing the specified ui.

  • Implementation of a bridge, let the refresh function and data needed to associate.

  • Monitor data changes, changed after the data refresh function calls by bridging methods.

  • ui change triggers a corresponding change in the dom event-specific data.

2, the realization of ideas

  • To achieve observer, redefining data, increase setter for each property on the data, change data getter to listen.

  • Achieve compile, scanning template template, extract instruction information of each node dom.

  • Directive to achieve, by the instruction information corresponding to the directive is instantiated instance, different types of directive functions have different refresh update.

  • Achieve watcher, so that the listener function with the directive property of the update function to do one to one observer, in order to achieve data changes update the view after.

3, module division

MVVM is currently classified as observer, compile, directive, watcher four modules.

4, the data monitoring module observer

Listens to achieve data through es5 specification object.defineProperty way.

5, the realization of ideas

Recursively traverse data, all data will be combined with the following attributes are set, get ways to achieve interception of all attributes.

Note: The object may contain attributes built array, the array has a push, pop, splice or the like to change the internal data.

At this approach is to change the prototype chain array, add a layer of custom push in the prototype chain, pop, splice way to do interception, these methods inside with our own callback function, and then calls the push native, pop, splice and other methods.

export function defineProperty(obj, prop, val) {
if (prop == '__observe__') {

    return;

}

val = val || obj[prop];

var dep = new Dep();

obj.__observe__ = dep;

var childDep = addObserve(val);

Object.defineProperty(obj, prop, {

    get: function() {

        var target = Dep.target;

        if (target) {

            dep.addSub(target);

            if (childDep) {

                childDep.addSub(target);

            }

        }

        return val;

    },

    set: function(newVal) {

        if(newVal!=val){

            val = newVal;

            dep.notify();

        }

    }

});
}

6, compiled module compiler

Realization of ideas:

  • Dom will traverse the stencil template again, it is stored in the document fragment frag

  • Traversing the frag, get attribute information node through Attributes, instruction information filtered through a regular expression attribute information, and thus to get the document nodes and element nodes
var complieTemplate = function (nodes, model) {

if ((nodes.nodeType == 1 || nodes.nodeType == 11) && !isScript(nodes)) {
paserNode(model, nodes);

if (nodes.hasChildNodes()) {

  nodes.childNodes.forEach(node=> {

    complieTemplate(node, model);

  })

}
}

};

7, command module directive

Instruction information such as: v-text, v-for, v-model and the like.

Each action command information needed to initialize and refresh function update instructions may be different, so we do it abstracts a separate module. Of course, there are also common, such as public property, unified watcher instantiated, unbind.

the update function instructions relevant to define how to render the particular update function ui, such as a simple vtext instruction is as follows:

vt.update = function (textContent) {
this.el.textContent = textContent;
};

9, the structure of FIG.

Design JS source code analysis repository to achieve │ easy mvvm)

9, data subscription module watcher

watcher function is to allow directive associate and observer module. Initialization time to do two things:

  • The update function module when the parameter passed directive, and stores its own update attribute.

  • The getValue call, so as to acquire a specific property value of the object data, before a further triggering the getter properties of the function defined in the observer.

Since the dep defineProperty variables defined in the function has a reference setter and getter function in the closure state dep variable is not released, in this case the getter is determined by the presence of Depend.target, acquires subscriber Watcher, published by who dep storage. Each has a unique attribute data of the dep variable, a record of all the information subscribers watcher, once property changes, call the setter function when the trigger dep.notify (), notify all subscribed watcher, and then perform all the attributes associated with refresh function, last updated designated ui.

watcher initialization part of the code:

Depend.target = this;

this.value = this.getValue();

Depend.target = null;

observer.js Code attribute definition:

export function defineProperty(obj, prop, val) {
if (prop == '__observe__') {

    return;

}

val = val || obj[prop];

var dep = new Dep();

obj.__observe__ = dep;

var childDep = addObserve(val);

Object.defineProperty(obj, prop, {

    get: function() {

        var target = Dep.target;

        if (target) {

            dep.addSub(target);

            if (childDep) {

                childDep.addSub(target);

            }

        }

        return val;

    },

    set: function(newVal) {

        if(newVal!=val){

            val = newVal;

            dep.notify();

        }

    }

});
}

10, a flowchart

Design JS source code analysis repository to achieve │ easy mvvm

11, summary

Wen basic demand mvvm library sorting, splitting, and one by one to achieve the split modules to achieve to achieve the overall function of the two-way binding, of course, currently mvvm library functions on the market will not stop at this, this is just to name a personal view of core code. If the problem is on the idea and realization, also please correct me, thank you for reading!

Original code: https://github.com/laughing-pic-zhu/mvvm

Want to learn more students can access several Lan community , and we can discuss together to learn ~

Guess you like

Origin blog.51cto.com/14463231/2435045