在vue规范中data里定义的数据xx,可以直接通过this.xx直接访问。这是有原因的,下面截取部分源码
const sharedPropertyDefinition = {
enumerable: true,
configurable: true,
get: null,
set: null
}
function proxy (target, sourceKey, key) {
sharedPropertyDefinition.get = function proxyGetter () {
console.log(this)
return this[sourceKey][key]
}
sharedPropertyDefinition.set = function proxySetter (val) {
this[sourceKey][key] = val
}
Object.defineProperty(target, key, sharedPropertyDefinition)
}
// 以下为仿照
function vue() {
this._data = {
aa: 'aaa',
bb: 'bb'
}
}
const vm = new vue()
const keys = Object.keys(vm._data)
let i = keys.length
while(i--) {
const key = keys[i]
proxy(vm, '_data', key)
}
vm.aa = 'a-a'
console.log(vm.aa) // 打印结果为a-a
以访问aa为例子,上面的代码其实写成下面的形式也是一样的
const sharedPropertyDefinition = {
enumerable: true,
configurable: true,
get: function proxyGetter () {
return this['_data']['aa']
},
set:function proxySetter (val) {
return this['_data']['aa'] =val
}
}
function vue() {
this._data = {
aa: 'aaa',
bb: 'bb'
}
}
const vm = new vue()
// 访问aa的时候就会走proxyGetter,拿到_data中的aa
Object.defineProperty(vm, 'aa', sharedPropertyDefinition)
vm.aa = 'a-a' // 为aa赋值时,就会走proxyGetter
//上图的proxy函数,其实是循环data中的变量,反复通过defineProperty为vm定义属性
console.log(vm.aa) // 结果为a-a