Skip to content

响应式对象

众所周知, vue2.x 中,数据响应式的底层原理式基于 ES2015 的Object.defineProperty 来实现的, 但是在 vue 工程中, 具体是怎么实现的呢, 跟着下文一探究竟

Object.defineProperty

Object.defineProperty 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象,语法如下:

js
Object.defineProperty(obj, prop, descriptor);

obj 是要在其上定义属性的对象;prop 是要定义或修改的属性的名称;descriptor 是将被定义或修改的属性描述符。

descriptor属性描述是一个对象,允许对对象的某个属性设置

  • 是否可枚举:enumerable
  • 是否可配置:configurable
  • 是否可修改:writable
  • 值:value
  • 获取器:get,在读取当前 key 的时候会调用 get 方法
  • 设置器: set, 在设置当前 key 的时候会调用 set 方法

initState(vm)

Vue 构造函数中调用了this._init(options)之后, 在_init执行了一系列的初始化方法, 其中就包含了initState(vm), 探索数据响应式原理, 主要和数据相关, 所以这里主要关注initState, 其余的暂时忽略

initState(vm)内部调用了下列方法

  • initProps(vm, opts.props)
  • initMethods(vm, opts.methods)
  • initData(vm)
  • initComputed(vm, opts.computed)
  • initWatch(vm, opts.watch)

同理, 仅关注initData(vm)

initData

initData方法内部, 首先会循环 data 中每一个 key, 对 key 进行 proxy 代理处理, 将vm._data.xxx代理为 vm.xxx

接着又对整个dataobserve处理:ob = observe(data)