Vue2中初始化数据做了些什么
我们定义在data中的数据,在vue初始化的时候做了以下几步:
- 在vue实例上添加
_data属性,把data中的属性赋值到_data中,我们可以通过this._data获取属性值 - 通过
Object.defineProperty递归遍历data劫持所有数据 - 通过
proxy函数,把data中的属性代理到Vue实例上
添加_data属性
data中有两种情况:
// 对象形式
data: {
name: 'zs'
}
// 函数形式
data(){
return {
name: 'zs'
}
}
我们通过判断是否为函数来获取data中的属性,这里需要通过call方式把this指向到Vue实例上,因为data中的数据可能会依赖Vue的其他模块,比如 vuex,不更改指向则获取不到Vue实例上的数据
// 在赋值的时候在vue实力上添加了一个_data属性,是和data相同的
data = vm._data = typeof data === 'function' ? data.call(vm) : data
把属性代理到Vue实例上
在平时的开发中,我们通常会使用this.xxx来获取或者修改data中的属性,但是我们只是在Vue实例中添加了一个_data属性,每次再调用时会非常麻烦this._data.xxx,所以我们通过proxy函数把数据代理到实例上
- 在数据完成了劫持之后,使用for in遍历data中的数据,通过
Object.defineProperty给实例添加数据,当我们使用this.xxx就等同于this._data.xxx,也是便捷于我们开发,而且代码漂亮许多
for (let k in data) {
proxy(vm, '_data', k)
}
function proxy(vm, source, key) {
Object.defineProperty(vm, key, {
get() {
return vm[source][key]
},
set(newValue) {
vm[source][key] = newValue
},
})
}