Home  >  Article  >  Web Front-end  >  Three-step explanation of vue implementation (with code)

Three-step explanation of vue implementation (with code)

不言
不言forward
2018-10-29 14:11:252210browse

The content of this article is about the three-step explanation of vue implementation (with code). It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.

Vue is a popular framework today. It can perform two-way data binding. Why is vue so popular? The reasons I know are roughly as follows?

1. The traditional operation of changing the dom structure is a very wasteful operation (that is, slow)
2. Putting the logic of changing the dom structure in the js layer can improve performance.
3. The separation of data and view is more in line with object-oriented programming. The implementation of mvvm

vue is also implemented using virtual dom like react. As for what virtual dom is, it is rendered through templates using js The resulting dom.

The steps to implement vue are probably these three steps:

1. Responsiveness: How does vue monitor the changes in each attribute value of dota?
2. Template engine: How is Vue’s template parsed and how are instructions processed?
3. Template rendering: How to add the data in data to the template and render it into html?

Step One: Responsiveness

The implementation of responsiveness mainly relies on the method of an object:

Object.defineProperty

This method can monitor changes in attributes in the object and perform logical processing

dome is as follows:

    var obj={}
    var _name ='zhangsan'
    Object.defineProperty(obj,'name',{
        get:function() {
            console.log('get')
            return _name
        },
        set: function(newVal) {
            console.log('set')
            _name=newVal
        }
    })

Here you change the value of name or access the value of name There will be printed information

And the simulation implementation in vue is probably like this:

        var vm ={}
        var data={name:'张三',age:20}
        var key,value;
        for(key in data) {
            (function(key){
                Object.defineProperty(vm,key,{  //绑定到vm上
                    get:function(){
                        console.log('get')
                        return data[key];
                    },
                    set:function(newVal){
                        console.log('set');
                        data[key]=newVal
                    }
                })
            })(key)  //闭包处理
        }

In fact, students who have studied Java must be familiar with this. Get can be directly generated in the Java class and set method

Second step: parse the template

The template must be converted into js code because:
1. Logical judgment (v-if, v-for), must This can only be achieved using js.
2. The rendering of virtual dom must be achieved using js. (render function)

Template 1

    <div id="app">
        <p>{{price}}</p>
    </div>

Render converted by template 1

           with(this) { //this就是vm
                return _c(
                    'p',
                    {
                        attrs:{'id':'app'}
                    },
                    [
                        // _c是createElement
                        // _v是createTextVNode
                        // _s是toString方法
                        _c('p',[_v(_s(price))])
                    ]
                )
            }

Template 2

    <div id="app">
        <div>
            <input v-model="title">
            <button v-on:click="add">submit</button>
        </div>
        <div>
            <ul>
                <li v-for="item in list">{{item}}</li>
            </ul>
        </div>
    </div>

Render converted by template 2

           with (this) {
                return _c(
                    'p',
                    { attrs: { "id": "app" } },
                    [
                        _c(
                            'p',
                            [
                                _c(
                                    'input',
                                    {
                                        //指令
                                        directives: [
                                            {
                                                name: "model",
                                                rawName: "v-model",
                                                value: (title),    //vm.title
                                                expression: "title"
                                            }
                                        ],
                                        domProps: {
                                            "value": (title) //vm.title 
                                        },
                                        on: {
                                            "input": function ($event) {
                                                if ($event.target.composing) return;
                                                title = $event.target.value
                                            }
                                        }
                                    }
                                ),
                                _v(" "),
                                _c(
                                    'button',
                                    {
                                        on: { "click": add }  //vm.add
                                    },
                                    [
                                        _v("submit")
                                    ]
                                )
                            ]
                        ),
                        _v(" "),
                        _c(
                            'p',
                            [
                                _c(
                                    'ul',
                                    _l(
                                        (list), function (item) {
                                            return _c(
                                                'li',
                                                [
                                                    _v(_s(item))
                                                ]
                                            )
                                        }
                                    )
                                )
                            ]
                        )
                    ]
                )
                 }

This is the render function used for rendering

The third step: Render the template plus data into html

vm._update(Vnode) {
    const prevVonde=vm._Vnode
    vm._Vnode=Vnode;
    if(!prevVnode) {  //如果没有之前的vnode,第一次渲染
        vm.$el=vm._patch_(vm.$el,Vnode)
    }else {
        vm.$el=vm._patch_(prevVnode,Vnode)
    }
}
function updataComponent() {
    //vm._reander就是解析模板的rende函数,返回了一个vnode
    vm._update(vm._render())
}

The vm_.patch_ here contains the complex diff algorithm. Rendering is based on differences in DOM. It uses a lot of recursive calls, and it involves a lot of efficiency issues. The world's martial arts is fast.

The above is the detailed content of Three-step explanation of vue implementation (with code). For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:segmentfault.com. If there is any infringement, please contact admin@php.cn delete