Vue3 和 Vue2 的响应式原理区别

Vue2 响应式是通过 Object.defineProperty() 劫持各个属性 getter 和 setter,在数据变化时发布消息给订阅者,触发相应的监听回调。

存在几个问题:

初始化时需要遍历对象所有 key,如果对象层次较深,性能不好
通知更新过程需要维护大量 dep 实例和 watcher 实例,额外占用内存较多
Object.defineProperty 无法监听到数组元素的变化,只能通过劫持重写数方法
动态新增,删除对象属性无法拦截,只能用特定 set/delete 等API 代替
不支持 Map、Set 等数据结构

Vue3 中使用原生的 proxy 代替,支持监听对象和数组的变化,并且多达13种拦截方法,动态属性增删都可以拦截,新增数据结构全部支持,对象嵌套属性只代理第一层,运行时递归,用到才代理,也不需要维护特别多的依赖关系,性能取得很大进步

 

 总结Proxy 代替 defineProperty 

Object.defineProperty 是 Es5 的方法,Proxy 是 Es6 的方法
defineProperty 不能监听到数组下标变化和对象新增属性,Proxy 可以
defineProperty 是劫持对象属性,Proxy 是代理整个对象
defineProperty 局限性大,只能针对单属性监听,所以在一开始就要全部递归监听。Proxy 对象嵌套属性运行时递归,用到才代理,也不需要维护特别多的依赖关系,性能提升很大,且首次渲染更快
defineProperty 会污染原对象,修改时是修改原对象,Proxy 是对原对象进行代理并会返回一个新的代理对象,修改的是代理对象
defineProperty 不兼容 IE8,Proxy 不兼容 IE11

 

上一篇:VUE3 之 全局组件与局部组件


下一篇:Vue3-setup