JS原生数据绑定原理

2019-02-02  本文已影响5人  wade3po

用过vue的人都知道,vue有一个特别好用的数据绑定,只要绑定了,你只要改变了这个数据,页面也会跟着渲染。其实原生的JS也是可以做到的,vue其实就是用了原生的原理。

Object.defineProperty,语法是Object.defineProperty(obj, prop, descriptor)

obj:就是一个对象;

prop:就是你要监听的obj里面的某个数据;

descriptor:目标属性所拥有的特性;

这三个都是必须的,前两个都好理解,第三个,说简单点就是这个方法自带的几个特性:Value、writable、enumerable、configurable和getter、setter,其中,getter、setter和Value、writable是不能一起用的。

configurable:true或false,属性是否能删除和再次设置,默认false;

enumerable:true或false,属性是否能枚举,默认false;

value:任意类型的值,默认undefined;

writable:true或false,属性是否能被重写,默认false;

value:

var obj = {}-------每个方法都要有,下面例子就不一一声明

//不设置value属性

Object.defineProperty(obj,"val",{

});

console.log( obj.val ); //输出undefined

//设置value属性

Object.defineProperty(obj,"val",{

value:"hello"

});

console.log( obj.val ); //输出hello

Writable:

//writable设置为false,不能重写。

Object.defineProperty(obj,"val",{

value:"hello",

writable:false

});

obj.newKey = "change";

console.log(obj.val); //输出hello

//writable设置为true,可以重写

Object.defineProperty(obj,"val",{

value:"hello",

writable:true

});

obj.val = "change";

console.log(obj.val); //输出change

enumerable:

//enumerable设置为false,不能被枚举。

Object.defineProperty(obj,"val",{

value:"hello",

enumerable:false

});

for( var val in obj ){

console.log( val );  //输出空

}

//enumerable设置为true,可以被枚举。

Object.defineProperty(obj,"val",{

value:"hello",

enumerable:true

});

//枚举对象的属性

for( var val in obj ){

console.log( val );  //输出val

}

configurable:

//configurable设置为false,不能被删除。

Object.defineProperty(obj,"val",{

value:"hello",

configurable:false

});

//删除属性

delete obj.val;

console.log( obj.val ); //输出hello

//configurable设置为true,可以被删除。

Object.defineProperty(obj,"val ",{

value:"hello",

configurable:true

});

//删除属性

delete obj.val ;

console.log(obj.val); //输出undefined

//configurable设置为false,不能再次修改特性。

Object.defineProperty(obj,"val",{

    value:"hello",

    configurable:false

});



//重新修改特性

Object.defineProperty(obj,"val",{

    value:"hello",

    configurable:true

});

console.log(obj.val); //报错:Uncaught TypeError: Cannot redefine property: val

//configurable设置为false,不能再次修改特性。

Object.defineProperty(obj,"val",{

value:"hello",

configurable:true

});

//重新修改特性

Object.defineProperty(obj,"val",{

value:"hello",

configurable:false

});

console.log(obj.val); //输出hello

现在说说最重要的getter和setter方法,数据绑定的主要方法。

<input type="text" id="val"/>

<span id="bind"></span>

<script>

var obj = {};

Object.defineProperty(obj,'hello',{

    set:function(val){

        document.getElementById('bind').innerHTML = val;

        document.getElementById('val').value = val;

    },

    get:function () {

        console.log('get方法被触发了');

        return 3;

    }

});

document.getElementById('val').onkeyup = function(e){

    obj.hello = e.target.value;

    console.log(obj.hello)

};

obj.hello = 999;

</script>

当我们监听input的键盘事件的时候,只要input里面的值改变了,只要obj.hello 赋值,就会触发set方法,这时候我们就可以在里面操作改变页面。只要调用obj.hello,就会触发get方法,这时候打印出来的obj.hello一直等于3,因为我们return的就是3,所以这边应该返回改变的值。这时候估计很多人会觉得都是监听,那还不如直接写在input的监听事件里面,其实不是的,只要你调用了obj.hello,页面的值就会变化。就像obj.hello = 999;那么页面的值就会是999;感兴趣的可以复制代码的方法,一个一个方法调用,就很容易明白原生JS的双向绑定。

欢迎关注 Coding 个人笔记 公众号

上一篇 下一篇

猜你喜欢

热点阅读