响应式注意事项
从源码了解了响应式的基础,我们应该明白在业务上注意什么?
不要赋值新对象
观察下列示例
const a = {
a: 1,
b: {
c: 2
}
};
new Oberserve(a);
a.b = {
c:2
}
function log(thisValue:unknown,oldValue:unknown){
return console.log(`new:${thisValue},old:${oldValue}`);
}
new Watcher(a,"b.c",log)
a.b.c = 3;
会打印吗?显然不会,重新赋值对象已经失去了响应式了。
不要新增或删除对象上的键
Object.defineProperty方法实现了观察对象上的键,它是遍历对象的键并转换为响应式,无法监测后续对象上键的改变。
所以,向object数据里添加一对新的key/value或删除一对已有的key/value时,它是无法观测到的 。此处不再举例。
不要索引数组改变其值
Vue中数组内的值的改变是没有响应式的。
const a = {
b: [1,2,3,4]
};
new Oberserve(a);
function log(thisValue:unknown,oldValue:unknown){
return console.log(`new:${thisValue},old:${oldValue}`);
}
new Watcher(a,function(){ return this.b[0] },log)
a.b[0] = 10;
//并不能响应
只能通过数组方法push,slice,unshift来响应。
这三个问题,Vue都注意到了,如果你有需求,可以Vue.set和Vue.delete保证响应式。
在Vue3中,响应式部分已经被Proxy重写,它可以监测到一个对象键的改变和数组的索引值改变,不存在上述问题。
不要在computed中对数据改动
考虑以下示例
new Watcher(a,function(this:typeof a,vm){
this.a++;
return this.a + this.e
},log)
//RangeError: Maximum call stack size exceeded
这会导致无限进入getter函数而爆栈