「Vue」区分数据监测 & 数据代理 & 数据劫持

871 阅读3分钟

很多学习过Vue2的小伙伴难以区分数据监测、数据代理、数据劫持这三个相近的概念,本文希望能够帮助大家理解和总结。

🤖 数据代理

1.1 何为数据代理

Vue中的数据代理就是通过vm对象来代理对data对象中属性的操作(读/写),它能够帮助我们更好地操作data中的数据。

1.2 Object.defineProperty()

要搞懂Vue数据代理这个概念,那我们就要从Object.defineProperty()入手,Object.defineProperty()是Vue中比较底层的一个方法,在数据劫持,数据代理以及计算属性等地方都或多或少的用到了此函数。
基本用法:

let person = {
     name: '张三',
     sex: '男'
}
//指定操作的对象、属性、配置对象
Object.defineProperty(person, 'age', {
     // 当有人读取person的age属性时,get函数(getter)就会被调用,返回值就是age的值
     get() {
          console.log('有人读取age属性了');
          return number
        },

     // 当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值
     set(value) {
            console.log('有人修改了age属性,且值是', value);
            number = value
      }
})

1.3 基本原理

  • 通过Object.defineProperty()把data对象中所有属性都添加到vm上
  • 为每一个添加到vm上的属性,都指定一个getter/setter
  • getter/setter内部去操作(读/写)data中对应的属性

举个例子,当我们访问vm身上的name时,就会调用getter方法获取到data中的name;当我们修改vm身上的name时,就会调用setter方法修改data中的name,从而实现通过vm对象代理对data对象的操作。

🔪 数据劫持

2.1 何为数据劫持

利用JavaScript引擎赋予的功能,检测对象属性变化,即:利用js的API将data中的数据变为 发生变化可被监测的,通俗讲就是数据发生了变化,会被某个东西捕获到,这就是数据劫持。

2.2 基本原理

  • Vue会监测到data中的所有属性,通过Object.defineProperty()为每个属性进行加工,配上一套的gettersetter
  • 升级过后的data会被放置在vm身上的_data中,从而实现页面响应式更新

👀 数据监测

3.1 何为数据监测

Vue会监视data中所有层次的数据,当data中的数据发生改变时,Vue就会重新解析模板,更新界面。

3.2 基本原理

监测对象中的数据

通过setter实现监视,且要在new vue时就传入要监测的数据
(1). 对象中后追加的属性,Vue默认不做响应式处理
eg:vm._data.studnet.sex='女'
(2). 如需给后添加的属性做响应式,请使用以下API:
Vue.set(target, propertyName/index, value)
vm.$set(target, propertyName/index, value)

监测数组中的数据

通过包裹数组更新元素的方法实现,本质就是做了两件事:
(1). 调用原生对应的方法对数组进行更新。
(2). 重新解析模板,进而更新页面(基于Observer函数)。

注意:

  1. 直接增加或删除属性,视图不会更新;
  2. 通过数组索引修改元素,视图不会更新;
  3. 使用数组API或Vue.set()修改数组元素,视图会随之更新;
  4. Vue.set() 和 vm.$set() 不能给 vm 或 vm的根数据对象(vm._data) 添加属性。

💬 总结

image.png 数据劫持:加工data,为每个属性配上gettersetter
options.data -> vm._data
数据代理:通过vm代理对vm._data中属性的操作。
vm._data.xxx -> vm.xxx
数据监测:data中数据发生变化,模板中用到数据的相应位置发生响应式改变。
vm.xxx = 'newValue' -> 界面更新