vue中的数据监听原理

46 阅读1分钟

实现一个简单版本的vue检测数据改变的代码

let data = {
  name: 'sakamoto',
  address: 'tokyo'
}

const obs =  new Observer(data)
console.log(obs)

let vm = {}
vm._data = data = obs

function Observer(obj) {
  const keys = Object.keys(obj)
  keys.forEach(key => {
    Object.defineProperty(this, key, {
      get() {
        console.log('get')
        return obj[key]
      },
      set(newVal) {
        console.log('set a new number, 解析新模板')
        obj[key] = newVal
      }
    })
  })
}

当数据变化时,如何被动获取检测数据的变化。 实现一个 Observer 函数,可以看到该函数内获取到数据之后,然后获取数据的所有key值 然后使用 defineProperty 来创建 Observer 的实例对象,此时对于 data 上的每一个值都会在 obs 重新创建,并且形成 get 以及 set 函数。

可以在控制台观察到

image.png

此时我们模仿 vm 的形式,创建一个 vm 对象,然后对 data 以及 vm 上的_data 赋值 obs,就可以得到类似于 vm 的对象结构。

image.png

此时我们改变 data 中的某一属性值时,就可以观察到 set 函数被调用。

image.png

但是这个简单版本的数据监听,仅限于这种简单的数据结构,如果 data 里再含有对象或者数据,那么就监听不到了。

let data = {
  name: 'sakamoto',
  address: 'tokyo',
  obj: {
    a: '1',
    b: '2'
  }
}

可以观察到 obj 里面的对象并没有形成 setget ,原因很简单,我们 observer 函数代码仅仅进行了比较简单的遍历,并没有深层次的去为内在的对象 obj 来创建 set 以及 getimage.png