vue数据双向绑定原理

vue数据双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现的,我们可以先来看一下通过控制台输出一个定义在vue初始化数据上的对象是什么。

var vm = new Vue({
    data: {
        obj: {
            a: 1
        }
    },
    created: function () {
        console.log(this.obj);
    }
});

结果:
浏览器截图
我们可以看到属性a有两个相对应的get和set方法,为什么会多出这两个方法呢?因为vue是通过Object.defineProperty()来实现数据劫持的。

Object.defineProperty( )是用来做什么的?它可以来控制一个对象属性的一些特有操作,比如读写权、是否可以枚举,这里我们主要先来研究下它对应的两个描述属性get和set,如果还不熟悉其用法,请点击这里查看更多用法

在平常,我们很容易就可以打印出一个对象的属性数据:

var Book = {
  name: 'JavaScript设计模式'
};
console.log(Book.name);  // JavaScript设计模式

如果想要在执行console.log(Book.name)的同时,直接给书名加上书名号,那要怎么处理呢?或者说要通过什么监听对象 Book 的属性值。这时候Object.defineProperty( )就派上用场了,代码如下:

var Book = {}
var name = '';
Object.defineProperty(Book, 'name', {
  set: function (value) {
    name = value;
    console.log('书名叫' + value);
  },
  get: function () {
    return '《' + name + '》'
  }
})
 
Book.name = 'JavaScript设计模式';  // 书名叫JavaScript设计模式
console.log(Book.name);  // 《JavaScript设计模式》

我们通过Object.defineProperty( )设置了对象Book的name属性,对其get和set进行重写操作,顾名思义,get就是在读取name属性这个值触发的函数,set就是在设置name属性这个值触发的函数,所以当执行 Book.name = ‘JavaScript设计模式’ 这个语句时,控制台会打印出 “书名叫JavaScript设计模式”,紧接着,当读取这个属性时,就会输出 “《JavaScript设计模式》”,因为我们在get函数里面对该值做了加工了。如果这个时候我们执行下下面的语句,控制台会输出什么?

console.log(Book);

浏览器截图
没错,vue就是通过这种方法来进行数据劫持的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章