美文网首页
Vue响应数据原理Object

Vue响应数据原理Object

作者: 铜牛彦祖 | 来源:发表于2018-06-23 16:34 被阅读0次

    Vue官网原文有解释:当你把一个普通的JavaScript对象传给Vue实例的data选项,Vue将遍历此对象所以的属性,并使用Object.defineProperty把这些属性全部转为getter/setter。

    • 数据代理 Object.defineProperty() 定义属性、改变属性的描述
    • 语法:Object.defineProperty(obj,prop,descriptor)
    • 参数: obj要在其上定义属性的对象,prop要定义或修改的属性的名称,descriptor将定义或修改的属性描述符

    数据描述 :

    • configurable 是否可以删除目标属性。默认为false
    • enumerable 此属性时候可以被枚举。默认为false
    • value 该属性对应的值,默认为undefined
    • writable 属性的值是否可以被重写,默认为false
    //在o身上定义一个b,b的值为123
    var o = {
      a : 1
    }
    Object.defineProperty(o,'b',{
      value: 123,
     
    })
    console.log(o); //  { a:1, b:123  }
    
    //在o身上定义一个b,b的值为123
    var o = {
      a : 1
    }
    Object.defineProperty(o,'b',{
      value: 123,
      writable: false,
      enumerable: false,
      configurable: true 
    })
    
    //对原有的属性a也可以进行限制
    Object.defineProperty(o,'a',{
      value: 123,
      writable: false,
      enumerable: false,
      configurable: true 
    })
    o.b = 90 //writable 默认值为false 所以b的值无法被修改
    
    for(var attr in o) {
      console.log(attr); //b无法被枚举,因为enumerable默认值是false
    }
    
    console.log(o); //  { a:1, b:123  }
    

    存取器描述 : 可以知道什么时候数据发生了改变

    • getter是一种获得属性值的方法
    • setter 是一种设置属性值的方法
    • 可以写configurable、enumerable
    • 不能写value、 writable
    var o = {
      a : 1
    }
    Object.defineProperty(o,'b'.{
      get(){
        console.log('取值');
        return 1
      },
      set(newValue){
        console.log('设置值',newValue);
      }
    })
    o.b = 10000;// 这里会出发 set   打印出 '设置值' 10000
    

    举例子:这种写法每次改变数据的时候都需要去渲染一遍

    <body>
       <button id="change_name">改变姓名</button>
       <button id="change_age">改变年龄</button>
       <p id="name">姓名:XXX</p>
       <p id="age">年龄:xxx</p>
       <script>
         var data = {
            name: 'leo',
            age: 18
         }
    
         //原生做法
         var namep = document.querySelector('#name');
         var age = document.querySelector('#age');
    
         var change_name = document.querySelector('#change_name');
         var change_age = document.querySelector('#change_age');
    
         namep.innerText = '姓名:'+ data.name;
         age.innerText = '年龄:'+ data.age;
    
         change_name.onclick = function(){
            data.name = 'jon';
            namep.innerText = '姓名:'+data.name;
         }
         change_age.onclick = function(){
            data.age = '60';
            age.innerText = '年龄:'+data.age;
         }
    
       </script>
    </body>
    

    举例子:Vue中的做法,只需要数据怎么变就可以了

    function observer(data,cb) {
        Object.keys(data).forEach(item => {
            reactive(data,item,data[item],cb)
        })
    }
    function reactive(obj,prop,value,cb){
        Object.defineProperty(obj,prop,{
          get(){
            return value;
          },
          set(newValue){
            value = newValue
            cb()
          }
        })
    }
    
    var data = {
        name: 'leo',
        age: 18
    }
    
    observer(data,function(){
        render()
    })
    console.log(data)
    //原生做法
    
    var namep = document.querySelector('#name');
    var age = document.querySelector('#age');
    
    var change_name = document.querySelector('#change_name');
    var change_age = document.querySelector('#change_age');
    
    function render(){
    namep.innerText = '姓名:'+ data.name;
    age.innerText = '年龄:'+ data.age;
    }
    
    render();
    
    change_name.onclick = function(){
        data.name = 'jon';
        
    }
    change_age.onclick = function(){
        data.age = '60';
        
    }
    

    相关文章

      网友评论

          本文标题:Vue响应数据原理Object

          本文链接:https://www.haomeiwen.com/subject/jwaryftx.html