前言
数据代理,是通过一个对象代理对另一个对象中属性的操作(读/写),作用是更加方便的操作data中的数据。想要理解Vue中的数据代理,我们需要先来认识一下Object.defineProperty()
这个方法。
Object.defineProperty()
官方定义:Object.defineProperty()方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。
简单的代码展现——
//动态的将number中的x的值赋值给张三的age属性
<script>
let number = {
x: 18,
y: 20,
}
let person = {
name: '张三',
sex: '男'
}
Object.defineProperty(person, 'age', {
// 当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
get() {
return number.x
},
// 当有人修改person的ag属性时,set函数(setter)就会被调用,且会收到修改的具体值
set(value) {
number.x = value
}
})
</script>
从上述代码和结果展示中,我们可以看到number和person之间是通过Object.defineProperty()
方法来实现数据传递,当访问person上的age属性时,就会调用get方法来读取number;当我们修改了person上的age属性时,就会调用set方法来改变number,相当于通过person对象操作了number这其中实现数据代理的核心就是Object.defineProperty()
方法。
关于Object.defineProperty的几点拓展:
Object.defineProperty(obj, prop, descriptor)
会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性Object.defineProperties(obj, props)
直接在一个对象上定义一个或多个新的属性或修改现有属性enumerable:true,
//控制属性是否可以枚举,默认值是falsewritable:true,
//控制属性是否可以被修改,默认值是falseconfigurable:true,
//控制属性是否可以被删除,默认值是falseget
:一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。set
:一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。
Vue中的数据代理
我们知道Vue响应式系统的核心就是数据代理,代理使得数据在访问时进行依赖收集,在修改更新时对依赖进行更新,这是响应式系统的核心思路。
通俗一点的理解就是:小明(data
)想要卖房子,他把这个房子交给了中介(Vue
)去处理,小红(vm
)正好看上了这套房子,于是就去问中介咨询关于这套房子的信息资料,这时中介就把从小明那里得到的信息反馈给小红。
简单代码展现——
<div id="app">
<h1>姓名:{{name}}</h1>
<h1>年龄:{{age}}</h1>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
name: '啊叼吖',
age: 18
}
})
console.log(vm);
</script>
我们来看一下Vue实例对象上有什么——age、name属性和_data对象,点开_data对象我们会发现里面的内容和我们写在data中的数据内容一样,且age、name属性和_data对象之间的变化也很有意思。这到底是为什么呢?
放一张图我们来解释解释:
其实在这里vm拿到data中的数据之后,立马将拿到的数据放在_data中(至于为什么会是_data那就是人家Vue的事情了),也就是说Vue实例中的data就是_data。但是我们正常调取vm中的属性值的时候,并没有通过_data来调取,这是因为Vue在拿到vm之后,往vm身上加了一个数据代理Object.defineProperty()
,把_data中的数据放到了vm身上一份,方便我们后续操作data中的数据。
如有错误,请指正。