Vue

2019-05-16  本文已影响0人  Dylean

Vue 数据双向绑定的原理

Vue 数据双向绑定是通过数据劫持和发布者-订阅者模式的方式来实现的。

首先看一下 Vue 初始化数据上的对象:

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

Vue 初始化数据上的对象的属性会多出 get 和 set 为什么会多出这两个方法呢,因为 Vue 是通过 Object.defineProperty() 来实现数据劫持的。

聊聊 Object.defineProperty()

在平时,一个普通的对象:

var Book = {
  name: 'vue权威指南'
};
console.log(Book.name);  // vue权威指南

如果我们想在执行 console 语句的时候,给书名加一个书名号怎么做呢?换一种说法,通过什么监听 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 = 'vue权威指南';  // 你取了一个书名叫做vue权威指南
console.log(Book.name);  // 《vue权威指南》

Object.defineProperty(a,b,c): a : 对象 b:要为对象的哪个属性改 get set 方法? c:具体get set 方法的改写。

我们通过 Object.defineProperty() 设置了对象的 name 属性,对其 get 和 set 进行了重写操作,get 就是在读 name 的时候自动触发,set 就是在写 name 的时候自动触发。

知道了 Vue 的数据劫持的原理,我们就可以实现一个简易版的 mvvm 双向绑定代码。

思路:

双向绑定

由图中可以看到,mvvm 表现在:数据变化更新视图,视图变化更新数据。

视图变化更新数据,我们可以使用事件监听的方法。关键是数据变化怎么更新视图呢?

数据变化更新视图的重点是,怎么才能知道数据变了,视图变化表现在当视图变化触发监听的函数。数据变化怎么知道呢?其实是利用 Object.defineProperty() 中的 set 函数,当数据改变的时候,会自动触发 set 函数,比如我们上面谈到的 name 变化的时候,对 name 设置的 set 函数会自动执行。我们将更新视图的代码写到 set 函数里面即可,就可以实现数据变化更新视图了。

Object.defineProperty() 数据变化更新视图

实现过程

首先要对数据进行劫持监听,我们需要设置一个监听器 Observer 用来监听属性的变化,如果属性发生变化,就告知订阅者 Watcher 看是否需要更新。(我理解为使用属性的东西)。因为订阅者是有多个的,所以我们需要用一个消息订阅器 Dep 来专门收集管理这些订阅者。

vue 全家桶包括什么?

优化方法

上一篇下一篇

猜你喜欢

热点阅读