zoukankan      html  css  js  c++  java
  • 从Object.definedProperty中看vue的双向数据的绑定

    前言

    Object.defineProperty是ES5中的方法,它可以直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。vue.js正式利用这种方法实现数据的双向绑定,以达到响应式的目的。

    1、语法

    Object.defineProperty(object, propertyname, descriptor)  //参数(3个且必须)

    2、参数详解

      3.1、object:要在其上添加或修改属性的对象。
      3.2、propertyname:一个包含属性名称的字符串。就是需要定义的属性和方法。
      3.3、descriptor:可以包含以下属性,默认情况下, writable, enumerable,configurable值为false

      value:属性的值

      writable:如果为false,属性的值就不能被重写,只能为只读了。

      enumerable:是否能枚举,也就是否能在for...in循环中遍历出来或在Object.keys中列举出来。

      configurable:如果为false,就不能再设置他的(value,writable,configurable)。

     还有两个方法 (双向数据绑定正是利用了这两个方法,即访问器 )get() 和 set()

    3、看看栗子

    var a= {}
        Object.defineProperty(a,"b",{
          value:111
        })
     console.log(a.b);//111
    

    就是给a对象添加b属性,并返回a对象;

    再比如:把描述设置为不可写; 

    4、访问器 set和get

    set();一旦属性被重新赋值,此方法被自动调用。
    get();一旦属性被访问读取,此方法被自动调用。
    不能同时设置访问器 (get 和 set) 和 wriable 或 value,否则会错。

    var a= {}
    Object.defineProperty(a,"b",{
      set:function(val){
        console.log("赋值时候调用我,我的新值是"+ val)
        },
      get:function(){
        console.log("取值的时候调用我")
        return 123
       }
    })
    a.b =520          // 赋值时候调用我,我的新值是520
    console.log(a.b)  // 取值的时候调用我, 返回我设置123,不是开始设置的520 

    5、简单双向数据绑定

    给对象a定义新的属性b,并且定义属性b的get和set方法,当a.b的时候会调用b属性的get方法,给b属性赋值的时候,会调用set方法,这就是修改数据的时候,视图会自动更新的关键.(只能兼容IE8以上的浏览器,vue也是如此!)。

    理解JavaScript中的双向数据绑定

    <label>输入:</label><input type="text" id="demo1"><br/>
    <label>输出:</label> <input type="textarea" id="demo2"></input>
    
    <script>
        var a={};
        var output=[];
        Object.defineProperty(a,'b',{   //给a对象添加b属性
            set:function(val){
                output['b']=val;
            },
            get:function(){
                return output['b'];
            }
        })
        var demo1=document.querySelector('#demo1');
        var demo2=document.querySelector('#demo2');
        demo1.onkeyup=function(){
            a.b=demo1.value;//给a对象添加b属性时候,触发了a的set方法,此时#demo1的value值赋值给output['b']。
            demo2.value=output['b'];
        }
    
    </script>
    

      

    6、再看看Object.defineProperty实践例子

    直接在原型上添加一个不可遍历的方法extend(),该方法可以把新对象赋值给旧对象;

    Object.defineProperty(Object.prototype, 'extend',{
      value : function(def, opt) {
            for(var key in opt){
                def[key] = opt[key];
            }
        return def;
      },
      writable: true,
      enumerable : false
    });
    
    function func(options){
        let def = {
            payType: 'wechat',
            buyType: -1,
            isCard: false,
            toUid: -1,
            couponId: -1
        };
     
        let opt = extend(def, options);
     
        this.isCardPay = opt.isCard;
        this.payType = opt.payType;
        .......
    }
     
    //使用
    fuc({
        payType: 'ali',
        buyType: 2,
        isCard: true,
        toUid: 123456,
        couponId: 667890
    })
    

      

     7、vue怎么实现数据双向绑定?

    vue.js 则是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的settergetter,在数据变动时发布消息给订阅者,触发相应的监听回调。

    这里写的很详细。

  • 相关阅读:
    Eclipse用法与技巧——导入工程时报错(already exist in the workspace)
    小F的2013应届校招历程小结
    java知识积累——单元测试和JUnit(二)
    vue 中的 .sync 修饰符 与 this.$emit('update:key', value)
    vue 中的 provide/inject
    2011/08/27 刷机器,遭遇白苹果,不可连接ipod服务器 的解决
    传输文件过程中遇到异常被中断
    窗体的置顶显示
    将截图图片放入内存(剪贴板)中
    WPF加载相对路径的图片的解决方法
  • 原文地址:https://www.cnblogs.com/leaf930814/p/6891254.html
Copyright © 2011-2022 走看看