Vue2 原理介绍
Vue2 是通过 Object.defineProperty 将对象的属性转换成 getter/setter 的形式来进行监听它们的变化,当读取属性值的时候会触发 getter 进行依赖收集,当设置对象属性值的时候会触发 setter 进行向相关依赖发送通知,从而进行相关操作。
由于 Object.defineProperty 只对属性 key 进行监听,无法对引用对象进行监听,所以在 Vue2 中创建一个了 Observer 类对整个对象的依赖进行管理,当对响应式对象进行新增或者删除则由响应式对象中的 dep 通知相关依赖进行更新操作。
Object.defineProperty 也可以实现对数组的监听的,但因为性能的原因 Vue2 放弃了这种方案,改由重写数组原型对象上的 7 个能操作数组内容的变更的方法,从而实现对数组的响应式监听。
Vue3 原理介绍
Vue3在原理上与Vue2类似,但进行了一些优化和改进。其中最重要的变化是引入了Proxy代理对象来实现响应式。Proxy能够捕捉到对象的属性访问和修改操作,使得Vue3能够更精细地追踪数据的变化,并且性能比Object.defineProperty更好。
Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。
React 原理介绍
React采用了虚拟DOM的原理来实现高效的UI更新。它将用户界面抽象成组件树的形式,每个组件都有自己的状态(state)和属性(props),当状态或属性发生变化时,React会通过对比前后两个虚拟DOM树的差异,最小化DOM操作来更新用户界面。
React组件要更注意性能优化,也就是控制自身要不要重新渲染,而Vue却不需要。这还是响应式数据带来的区别,Vue能准确的知道数据变更后会触发哪些组件进行更新。而React中State变化以后,没有优化的情况下,会导致使用State及其所有子组件进行重渲染。
虚拟DOM
虚拟 DOM(Virtual DOM)本质上是JS 和 DOM 之间的一个映射缓存,它在形态上表现为一个能够描述 DOM 结构及其属性信息的 JS 对象。它主要存储在内存中。主要来说:
什么是虚拟DOM?
- 虚拟dom是一个js对象,存储在内存之中。
- 虚拟dom能够描述真实dom(存在一个对应关系)
- 当数据变化的时候,生成新的DOM,对比新旧虚拟DOM的差异,将差异更新到真实DOM上
虚拟DOM的优点?
- 减少 DOM 操作:虚拟 DOM 可以将多次 DOM 操作合并为一次操作
- 研发效率的问题:虚拟 DOM 的出现,为数据驱动视图这一思想提供了高度可用的载体,使得前端开发能够基于函数式 UI 的编程方式实现高效的声明式编程。
- 跨平台的问题:虚拟 DOM 是对真实渲染内容的一层抽象。同一套虚拟 DOM,可以对接不同平台的渲染逻辑,从而实现“一次编码,多端运行”
当每一次UI更新时,总会根据render重新生成最新的VNode,然后跟以前缓存起来老的VNode进行比对,再使用Diff算法(框架核心)去真正更新真实DOM(虚拟DOM是JS对象结构,同样在JS引擎中,而真实DOM在浏览器渲染引擎中,所以操作虚拟DOM比操作真实DOM开销要小的多)
两者对diff算法的优化
- tag不同认为是不同节点
- 只比较同一层级,不跨级比较
- 同一层级的节点用key唯一标识,tag和key都相同则认为是同一节点
Vue2的核心Diff算法采用了双端比较的算法,同时从新旧children的两端开始进行比较,借助key值找到可复用的节点,再进行相关操作。相比React的Diff算法,同样情况下可以减少移动节点次数,减少不必要的性能损耗,更加的优雅。