【Vue高级知识】细谈Vue 中三要素(响应式+模板+render函数)

Vue 中三要素的是什么?

响应式:

    // 如何让实现响应式的呢?
    let obj = {};
    let name = 'zhangsan';
    Object.defineProperties(obj, name, {get : function() {
      console.log('name' , name)
    }, set : function() {
        console.log('name' , name)
    }})
    
    
    // 1. 关键是理解Object.defineProperty
    // 2. 将data的属性代理到vm上面的
    let mv = {};
        let data = {
            price: 100,
            name: 'zhangsan'
        };
        for (let key in data) {
            (function (key) {
                Object.defineProperty(mv, key, {
                    get: function () {
                        console.log('get val');
                        return data[key];
                    },
                    set: function (val) {
                        console.log('set val');
                        data[key] = val;
                    }
                })
            })(key);
        }

Vue中如何解析模板?

模板是什么?

    <div id="app">
        <div>
            <input v-model="title">
            <button v-on:click="add">submitbutton>
        div>
        <ul>
            <li v-for="item in list">{{item}}li>
        ul>
    div>
 // 1(*****). 模板实际上就是一个字符串………………(vue中的模板的本质)
 // 2. 模板有逻辑,如v-if, v-for
 // 3. 与html格式很像,但是有很大的区别
 // 4. 最终还是要转换为html来显示
 // 5(*****). 模板最终必须转换成JS代码,因为:
 //   (1)有逻辑(v-if v-for):必须用JS才能实现(图灵完备)
 //    (2) 转换成HTML来渲染页面,必须用JS才能实现
 //    (3) 因此,模板最终要转换成为一个JS函数(render函数)

render函数?

with的用法
var obj = {
    name: 'zhangsan',
    age: 20,
    getAddress(){
        alert('shanghai');
    }
}

// 不使用with
function fn() {
  alert(obj.name);
  alert(obj.age);
  obj.getAddress();
}

// 使用with(代码不易维护!!!)
function fn1() {
  with(obj){
      alert(name);
      alert(age);
      getAddress();
  }
}

fn();
fn1();

render函数的实现机制?
<div id='app'>
    <p>{{price}}</p>
</div>

// 使用with限制这个作用域里面的this
with(this) {
    return _c(                          // this._c
        'div',
        {
            attrs: {"id" : "app"}       // id=app
        },
        [
            _c('p', [_v(_s(price))])    // this._c('p', [_v(_s(price))])
        ]
    )
}


// 实现一个自己的render函数
var vm = new Vue({
        el: '#app',
        data: {
            price: 100
        }
    });

    function render() {
        with (vm) {
            return _c(
                'div',
                {
                    attrs: {'id': 'app'}
                },
                [
                    _c('p', [_v(_s(price))])
                ]
            );
        }
    }

    function render() {
        return vm._c(
            'div',
            {
                attrs: {'id': 'app'}
            },
            [
                // vm._v 转换为一个文本节点
                // vm._s 转换为一个字符串
                // vm._c 转换为一个DOM节点
                vm._c('p', [vm._v(vm._s(price))])
            ]

        );
    }

render函数与vdom?

<div id="app">
        <div>
            <input type="text" v-model="title">
            <button @click="add">submitbutton>
        div>
        <div>
            <ul>
                <li v-for="item in list">{{item}}li>
            ul>
        div>
    div>
with (this) {
    // this 就是vm
    return _c(
        'div',
        {attrs: {"id": "app"}},
        [
            _c('div',
                [
                    _c('input', {
                        directives: [{
                            name: "model",
                            rawName: "v-model",
                            value: (title),
                            expression: "title"
                        }],
                        attrs: {"type": "text"},
                        domProps: {"value": (title)},
                        on: {
                            "input": function ($event) {
                                if ($event.target.composing) return;
                                title = $event.target.value
                            }
                        }
                    }),
                    _v(" "),
                    _c('button',
                        {
                            on: {
                                "click": add
                            }
                        },
                        [_v("submit")]
                    )
                ]
            ),
            _v(" "),
            _c('div',
                [
                    _c(
                        'ul',
                        // 这里返回的是一个数组(li标签组成的数组)
                        _l((list), function (item) {
                            return _c('li', [_v(_s(item))])
                        }), 0
                    )
                ]
            )
        ]
    )
}

// view --->  data ---> 使用input的事件绑定 ---> 更新页面数据到data
// data --->  view ---> defineProperty --->  同步数据到页面

vm._c是什么,render函数返回了什么?

  1. vdom: 使用js模拟DOm结构
  2. snabbdom: h函数和patch函数
    Vue中的v_c:就是相当于snabbdom函数的h函数
    patch函数:首次渲染和数据更新触发
    vm._update(vnode) {
        const prevNode = vm._vnode;
        vm._vnode = vnode;
        if (!prevNode) {
            // 首次渲染的时候
            vm.$el = vm.__patch__(vm.$el, vnode);
        }
        else{
            vm.$el = vm.__patch__(prevNode, vnode);
        }
    }
    
    // 开始更新vue组件(修改data的属性的时候,Object.defineProperty)
    function updateComponent() {
      vm._update(vm._render());
    }

你可能感兴趣的:(javascript,JavaScript学习,Javascript高级,玩转前端JavaScript)