zoukankan      html  css  js  c++  java
  • VUE计算属性原理

    先温习下Object.defineProperty

    var obj = {};
    function defineReactive(obj,key,val){
        //obj.a读写,deps和val闭包储存。
        //defineProperty只能定义一次。
        Object.defineProperty(obj,key,{
            //观察者模式
            get:function(){
                return val;
            }
        });
    }
    defineReactive(obj,'a',0);
    console.log("obj",obj);
    obj.a = 10;
    console.log("obj.a",obj.a);  // 0,定义无效,貌似只能赋值一次
    defineReactive(obj,'a',8);
    console.log("obj.a",obj.a);  //Cannot redefine property: a

    代码:

    var obj = {};
    var Dep = null;
    function defineReactive(obj,key,val){
        var deps = [];
        //obj.a读写,deps和val闭包储存。
        Object.defineProperty(obj,key,{
            //观察者模式
            get:function(){
                if(Dep){
                    //console.log("Dep is:",Dep);
                    deps.push(Dep);
                }
                console.log("valx is:",val);
                return val;
            },
            set: function(newVal){
                val = newVal;
    //给a赋值的时候,func也执行了,同时b的值也出来了,难点就是两个函数中的变量都闭包了,deps,value。
    //通过deps保存另外一个函数的func。同时defineReactive能执行defineComputed的func,这个是很少见的, deps.forEach(func
    => func()); } }); } //obj.b只读 function defineComputed(obj,key,func){ func = func.bind(obj); var value; //闭包起来,全局私有变量 Dep = function(){ value = func(); }; value = func(); //执行了 this.a-->get-->打印val = 0; Dep = null; // console.log("Dep isx:",Dep); // 大量闭包,直接给b赋值没有效果,只能读取obj.b了。 Object.defineProperty(obj,key,{ get:function(){ return value } }); } defineReactive(obj,'a',0); defineComputed(obj,'b',function(){ var a = this.a; // 这里只执行一次就执行了deps.push(Dep)。 return a+1; }); console.log(obj.b); // console.log("obj.a=",obj.a); console.log("obj.a=",obj.a); obj.a +=1; //obj.a = obj.a + 1; console.log(obj.b); obj.a +=1; console.log(obj.b); obj.a +=1; console.log(obj.b);

     很绕,难点是下面代码会执行两次a的get函数。第二次在set函数中的执行value = func(); func函数有this.a中执行了get。并+1赋值给闭包变量value。set函数结束之后。obj.a + 1;而

    obj.a +=1;  //obj.a = obj.a + 1;

    vue对computer中的属性处理分两步,

    先处理为vm._computedWatchers对象,每个key对应一个watch实例。watch在初始的时候执行。

    if (this.computed) {
          this.value = undefined
          this.dep = new Dep()  //初始化dep
        } else {
          this.value = this.get()
        }

    后是给key都赋值vm中,并且vm.key也进行数据劫持:

     Object.defineProperty(target, key, sharedPropertyDefinition)
    // sharedPropertyDefinition.get = shouldCache
    //      ? createComputedGetter(key)
    //      : userDef
    //    sharedPropertyDefinition.set = noop

    createComputerGetter(key) 是关键:它和上面的原理类似。接下来mount,

    updateComponent = () => {
        vm._update(vm._render(), hydrating)
    }

    _render()执行:vnode = render.call(vm._renderProxy, vm.$createElement) 得到一个VNode。render是在Vue.prototype.$mount 解析模板形成的AST。

    _update会到VNode映射到Dom节点中去,

  • 相关阅读:
    web安全之ssrf
    web安全之sql注入布尔注入
    web安全之sql注入报错型注入
    web安全之sqlload_file()和into outfile()
    浅谈 FHQ-Treap
    (菜鸟都能看懂的)网络最大流最小割,Ford-Fulkerson及Dinic详解
    浅谈最小生成树
    浅谈强连通分量(Tarjan)
    DP-DAY3游记
    关于01背包问题
  • 原文地址:https://www.cnblogs.com/liuyinlei/p/9367164.html
Copyright © 2011-2022 走看看