一、什么是数据代理
数据代理:通过一个对象代理对另一个对象中属性的操作(读/写)
通俗理解为页面中呈现的东西如果你想要修改,需要先将数据传到一个中间人手中,有中间人向Vue汇报要修改的内容,最后修改成功。
二、数据代理的原理
想要理解Vue中的数据代理,就要先提到一个很重要的API “Object.defineProperty()”,它会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
Object.defineProperty()内部原理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Document</title>
</head>
<body>
<script>
let person = {}
// set和get中的this都是当期对象
Object.defineProperty(person,'name',{
set(a){
// 当修改person.name时,set被调用,set会收到修改后的值
console.log('set被调用了',a);
},
get(){
// 当读取person.name时,get被调用,get的返回值是name的值
console.log('get被调用了');
return 100;
}
})
// 修改
person.name = 'xinxin'
// 读取
// console.log(person.name);
</script>
</body>
</html>
而数据代理就是依托这种原理,实现数据代理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Document</title>
</head>
<body>
//配置对象data中的数据,会被收集到vm._data中,然后通过
//Object.defineProperty()让vm上拥有data中所有的属性
//当访问vm的msg时,返回的是data当中同名属性的值
//当修改vm的msg时,修改的是data当中同名属性的值
<script>
let _data = {msg:'小学'};
let vm = {};
Object.defineProperty(vm,'msg',{
set(value){
_data.msg = value
},
get(){
return _data.msg
}
})
</script>
</body>
</html>
总结
有没有疑问这个数据为什么不能直接修改呢?
也很好理解,为了提高效率,如果我们直接修改内容,Vue中要监测的东西很多,他要多方位监测你要修改的地方,但是如果将要修改的地方全部存储到_data中,Vue就可以直接监测_data内容,从而提高效率。