# 数据代理

平时开发 Vue 项目的时候,我们发现无论是 data 中的数据还是 props 中数据都可以使用 this 来访问,这就是数据代理,接下来我们来看看 Vue 中是如何实现

Vue 源码做数据代理部分的功能是在文件 /src/core/instance/state.js 中处理的

可以找到关键代码就是一个函数:

const sharedPropertyDefinition = {
  enumerable: true,
  configurable: true,
  get: noop,
  set: noop
}
export function proxy (target: Object, sourceKey: string, key: string) {
  sharedPropertyDefinition.get = function proxyGetter () {
    return this[sourceKey][key]
  }
  sharedPropertyDefinition.set = function proxySetter (val) {
    this[sourceKey][key] = val
  }
  Object.defineProperty(target, key, sharedPropertyDefinition)
}

找到庐山真面目了,原来是使用了 Object.defineProperty 中的 get 方法和 set 方法

proxy 函数中,第一个参数就是数据要代理的对象,第二个参数就是数据源,第三个参数就属性 key 名称

# 例子

	const sharedPropertyDefinition = {
		enumerable: true,
		configurable: true,
		get: function () {

		},
		set: function () {

		}
	}
	function proxy (target, sourceKey, key) {
		sharedPropertyDefinition.get = function proxyGetter () {
			return sourceKey[key]
		}
		sharedPropertyDefinition.set = function proxySetter (val) {
			sourceKey[key] = val
		}
		Object.defineProperty(target, key, sharedPropertyDefinition)
	}
	const data = { name: 'lanjz', level: 10 }
	const d = {}
	Object.keys(data).forEach((ind) => proxy(d, data, ind))
    console.log(d.name) // lanjz
    d.level = 999
    console.log(data.level) // 999

# 总结

利用 Object.defineProperty 劫持数据的访问和更新,当 get 时从其它地方获取数据并返回,当 set 时再手动改变数据来源