原文链接:https://www.jianshu.com/p/4394009f53b9
Vue是怎么做到在我们更新了data之后就更新视图的呢?
在我们new Vue 之后,生成的实例就是data的代理,data一发生改变,就会被setter知道这个时候就帮我们去更新视图。
什么是getter&setter?
let 我 = {
姓: "孙",
名: "笑川",
get 姓名(){
return `我叫${this.姓}${this.名}`
},
set 姓名(arr){
this.姓 = arr[0]
this.名 = arr[1]
}
}
只要在函数上加了get,可以这样去调用:
我.姓名 //输出 孙笑川
只要在函数上加了set,可以这样去设置:
我.姓名 = ["吴","彦祖"]
我.姓 // 吴
我.名 // 彦祖
Object.defineProperty
如果要给"我"这个对象,添加一新的可以get/set的属性"长的帅"
let _长的帅 = null
Object.defineProperties(我,'长的帅',{
get(){
return _长的帅
},
set(value){
_长的帅 = value
}
})
这样就可以设置"我"的"长的帅"属性了
我.长的帅 = true
看上去这样做并没有什么好处,实际上是有的,比如我可以禁止设置"我"的"长的帅"属性为false
let _长的帅 = null
Object.defineProperties(我,'长的帅',{
get(){
return _长的帅
},
set(value){
if(value==false) return
_长的帅 = value
}
})
但其他人也是可以通过这种方法去改"长的帅"属性的,这个时候就需要上代理
function proxy({ data }) {
Object.defineProperty(我, "长的帅", {
get() {
return data.长的帅;
},
set(value) {
if (value == false) return;
data.长的帅 = value;
}
});
return 我;
}
我 = proxy({ data: { 长的帅: undefined } });
但是这样还不算安全,如果我要设置一个复杂的对象,想用外部变量,这样还是会被修改,比如这样
function proxy2({ data }) {
let value = data.长的帅
Object.defineProperty(data, "长的帅", {
get() {
return value;
},
set(newValue) {
if (newValue == false) return;
value = newValue;
}
});
Object.defineProperty(我, "长的帅", {
get() {
return data.长的帅;
},
set(value) {
if (value == false) return;
data.长的帅 = value;
}
});
return 我;
}
这样就安全了,被代理的对象发生变化时会被setter知道,修改的数据就都要经过它的手,它收到数据后就会去更新视图。