所谓响应式指的是当A数据变化后,作为依赖A的变量B也将随之发生变化。Vue3利用了proxy的handler中操作get和set完成了大部分数据的劫持代理。
1、什么是响应式
所谓响应简单举个例子就是指当A变化后,作为依赖A的B也将随之发生变化。A的变化会主动改变B。
2、响应式的基本使用
const count = ref(1);
const dobuleCount = count.value * 2;
count.value = 2;
console.log(count.value,dobulecount) // 2,4
const introduce = reactive({ name: "张三", age: 18 })
introduce.name = "李四"
console.log(introduce) // { name: "李四", age: 18}
3、响应式的基本流程
- 判断等待代理的变量是否是对象,如果是不是直接返回等待代理的变量,如果是进行步骤二
- 判断等待代理的变量是否已经代理,并且是否使用
reactive或readonly(定义对象非响应式)、或未使用readonly包含reactive定义了(因为结论是直接返回,但是readonly的结果不具备响应式),如果是则直接返回,如果没有进行步骤三
但如果这里非要使用
readonly(reactive())定义对象的话,实际应该还是被重新代理了,但是readonly在set时会进行拦截进行“不允许修改”的提醒
- 判断等待代理的变量是否已经代理过,如果已代理过,则直接返回之前缓存的已代理对象,如果没有进行步骤4
- 代理对象,对象分类型处理,将Object、Array合并处理,Map、Set、weakMap、weakSet合并处理
- 返回被代理完成的对象
4、相较于Vue2,Vue3的响应式设计优点在哪?
- 相较于
defineProperty,proxy能够代理更多类型数据,比如可以代理Map、Set等 defineProperty代理对象时,需要遍历对象对每个属性逐个代理,proxy则不需要,遍历过多就会导致性能下降,因此不建议使用太深层次的响应式数据proxy对数组的处理更方面(待定)- ...待补充
5、proxy的缺点
- 兼容性较差,不支持老版ie,对大多数人来说其实影响不大
5、响应式的缺点
- 不能使用解构赋值解构响应式变量(原因:解构赋值的过程并不是从
get进行的); - 根据文档描述定义,ref应当用来使用基本类型数据,
reactive用来定义其他类型数据,但在实际应用过程中,reactive有时候会带来一些小麻烦,比如:
批量更新
reactive包裹的数据时,无法直接替换reactive定义的变量,这会导致丢失响应性。这就不太适用于刷新操作,因为刷新后需要重新赋值。但可以考虑使用ref,只是不太符合规范
3.ref定义的响应式变量访问繁琐,需要使用.value进行配合访问。