# vue 监测数据改变的原理
# 实现:双向绑定的代理功能
以 vue 中的 data 属性为例,vue 中定义了 data 属性后做了三件事 1.直接拿到 data 中的数据并加到自身当中,如 vue 实例赋值给 vm,它就有了 vm.name 等 data 中的值 2.在 vm 中又加入了_data 属性,与 data 属性一模一样,只是前缀加了下划线 3.将_data 中的各属性值与 vm 相对应的值进行代理,即监视或双向绑定
# 例一:
<script>
Vue.config.productionTip = false//阻止vue在启动时产生生产提示,可以忽略
let data = {
name: "周杰伦",
age: 18
}
Object.defineProperty(data, 'name', {
get() {
return data.name
},
set(val) {
data.name = val
}
})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
貌似好像实现了双向绑定,但是出现逻辑错误,即绑定了自身,无限递归,所以 vue 创建了一个 _data 属性用来代理
# 例二:
<script>
Vue.config.productionTip = false//阻止vue在启动时产生生产提示,可以忽略
let data = {
name: "周杰伦",
age: 18
};
let obs = new Observer(data);
function Observer(obj) {
const keys = Object.keys(obj);
keys.forEach(k => {
Object.defineProperty(this, k, {//这里this指向 Observer的实例对象
get() {//因为这里k是用于遍历的变量,所以获取属性值不能是obj.k只能是obj[k]的形式
return obj[k]
},
set(val) {
obj[k] = val
}
})
})
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
实现了 obs 与 data 的监视