Vue 的数据响应式原理

 

一、理解Vue的设计思想

MVVM框架的三要素:数据响应式、模板引擎及其渲染

(1) 数据响应式:监听数据变化并在视图中更新

  • Object.defineProperty()
  • Proxy

(2) 模版引擎:提供描述视图的模版语法

  • 插值:{{}}
  • 指令:v-bind,v-on,v-model,v-for,v-if

(3) 渲染:如何将模板转换为html

  • 模板 => vdom => dom

 

二、数据响应式原理

数据变更能够响应在视图中,就是数据响应式。vue2中利用 Object.defineProperty() 实现变更检测。

Vue 的数据响应式原理_第1张图片

 

 三、响应式原理实现

(1)代码:

// TODO 定义一个对象响应式原理

function defineReactive(obj, key, val) {
  // TODO 1。处理办法
  observe(val)
  Object.defineProperty(obj, key, {
    get() {
      console.log('Get方法:', val)
      return val
    },
    set(newVal) {
      if (val !== newVal) {
        val = newVal
        console.log('Set方法:', val)
        // update(val)
        // TODO 2。问题2处理:obj.ccc赋值时,会进入到set拦截器,判断newval值为对象,我们需要对覆盖的这个对象做处理
        if(typeof newVal === 'object') {
          observe(newVal)
        }
      }
    }
  })
}

// 更新函数
function update(val) {
  document.getElementById('#app').innerHTML = val
}

// 处理对象的响应式,遍历对象中的所有key,对其做响应式处理
function observe(obj) {
  if (typeof obj !== 'object' || obj == null) {
    return;
  }
  Object.keys(obj).forEach(key => {
    defineReactive(obj, key, obj[key])
  })
}
// TODO 3。处理新增的属性,增加响应式
function set(obj, key, val) {
  defineReactive(obj, key, val)
}

var obj = {
  foo :'foo',
  boo: '123',
  ccc: {
    test: 'test',
    test2: 'test2'
  }
}
// 将obj 注册为响应式
observe(obj)

// TODO 1。obj.ccc 是一个对象,对象内部也要实现响应式处理
obj.ccc.test
// TODO 2。原本已经给最初赋值的 obj.ccc = {} 做了响应式的处理,但是下面又对他重新覆盖,导致,覆盖的内容不能响应
obj.ccc = {test:1}
obj.ccc.test
// TODO 3。新增一个对象,是没实现响应式处理,要自己实现一个set 方法
// obj.dong = 'dong'
set(obj, 'dong', 'dong')
obj.dong

// 每一秒触发一次对象的set,并更新视图View
// setInterval(() => {
//   obj.foo = new Date().toLocaleTimeString()
// }, 1000)

 

(2)实现结果:

传入的对象都实现了set 和 get 的监听。

Vue 的数据响应式原理_第2张图片

你可能感兴趣的:(Vue,深入浅出)