Vue的Watch最通的方式我们都知道,直接静态写死
export default{
data(){
return {
b:13,
c:23,
obj:{}
}
}
watch:{
["a"](val){
console.log("new value is" + val);
}
},
computed:{
a(){
return this.b + this.c;
}
}
}
再动态一些,比如动态增加了某个变量后,我们要watch它,咋整
onClick() {
this.$set(this.obj , "var1" , 14);//注意用$set
this.$watch(`obj.var1` , (newVal)=>{ console.log("new val " + newVal)});
}
但是如果这个变量本身是需要get set的呢?
Object.defineProperty(this.obj , "var1" , {
get(){this._var1},
set(val){this.__val1=val}
}
这样搞是不行的,因为this.obj.var1变量将不能参与vue的watch ,computed 等过程,因为vue也是通过defineProperty来搞数据绑定的,如果要新增加一个变量,提供一个理论基础的代码
addProperty(){
let __this = this;
let test = function() {
return __this.b + __this.c;
};
this.$watch(test, newVal => {
__this.$set(__this.obj , "test" , newVal)
});
}
这样,就给__this.obj增加了一个test的变量,并且它的值会和 b , c的和绑在一起 经过上述总结,可以抽离出一个API
function VueDefineProperty(target, propName, value) {
let __this = this;
if (!value) {
return;
}
if (typeof value.get != "function") {
return;
}
__this.$watch(value.get, newVal => {
__this.$set(target, propName, newVal);
});
if (typeof value.set != "function") {
return;
}
// eslint-disable-next-line no-prototype-builtins
if(target.hasOwnProperty(propName) == false){
__this.$set(target , propName , null);
}
__this.$watch(()=>target[propName], value.set);
}
需要注意的是
if(target.hasOwnProperty(propName) == false){
__this.$set(target , propName , null);
}
这一行的意义重大,因为watch在最初会进行一次get运算,来确定到底会波及到那些变量。如果最开始没有该变量,那watch就会失效的 使用的方法
this.VueDefineProperty(this.obj, "abc" , {
get: () => {
return this.data1.data11.a2;
},
set(val) {
console.log("value set " + val);
this.data1.data11.a2 = val;
}
});