react , vue 的实现原理比较
文章目录
react vue 相同点
以虚拟dom和diff算法为核心,通过操作数据来操作dom。
虚拟dom将2次数据改变的dom树结构生成2个js对象,以diff算法比较2个对象的异同点,若相同,则不更新dom;
若遍历到某一个节点时,发现异同点,则停止diff算法,更新该节点的所有子节点的dom结构.
1,都是用了Virtual DOM。
2,都提供了响应式和组件化的视图组件。
3,都将注意力集中保持在核心库,而将其他功能如路由和全局状态管理交给相关库。
react vue 不同点
vue通过getter、setter监听数据数据变化,react通过比较引用的方式监听数据变化,需要使用PureComponent优化.
1,React中,当某组件的状态发生改变时,它会以该组件为根,重新渲染整个组件子树,而在Vue中,组件的依赖是在渲染的过程中自动追踪的,所以系统能准确知晓哪个组件确实需要被重新渲染。
2,Vue的路由库和状态管理库都由官方维护支持且与核心库同步更新,而React选择把这些问题交给社区维护,因此生态更丰富。
3,Vue-cli脚手架可进行配置
Vue中有三种方式可以实现组件通信:父组件通过props向子组件传递数据或者回调,虽然可以传递回调,但是我们一般只传数据;子组件通过事件向父组件发送消息;通过V2.2.0中新增的provide/inject来实现父组件向子组件注入数据,可以跨越多个层级。
React中也有对应的三种方式:父组件通过props可以向子组件传递数据或者回调;可以通过 context 进行跨层级的通信,这其实和 provide/inject 起到的作用差不多。React 本身并不支持自定义事件,而Vue中子组件向父组件传递消息有两种方式:事件和回调函数,但Vue更倾向于使用事件。在React中我们都是使用回调函数的,这可能是他们二者最大的区别。
从实现原理上来说,最大的区别是两点:Redux使用的是不可变数据,而Vuex的数据是可变的,因此,Redux每次都是用新state替换旧state,而Vuex是直接修改。Redux在检测数据变化的时候,是通过diff的方式比较差异的,而Vuex其实和Vue的原理一样,是通过getter/setter来比较的,这两点的区别,也是因为React和Vue的设计理念不同。React更偏向于构建稳定大型的应用,非常的科班化。相比之下,Vue更偏向于简单迅速的解决问题,更灵活,不那么严格遵循条条框框。因此也会给人一种大型项目用React,小型项目用Vue的感觉。
vue
初始化vue的时候,在dom处理方面,vue会把template转化成render方法,拿到render方法后,转化成虚拟dom,在数据方面,会把data里的数据变成响应式的数据,每个节点都是响应式的.
Object.defineProperty({
get: () => {
/**
* 1、依赖收集,
* 2、收集是watch里完成的,new Watch的时候就会触发get
* 3、在watch构造函数里,会把一个全局的target对象指向this,也就是一个watch实例
* 4、把watch放进dep队列
* 5、把target=undefined
*/
},
set: () => {
/**
* 1、数据发生改变的时候,触发此钩子,
* 2、遍历当前dep队列里的watch对象,以此执行,watch.update,更新对象在process.nextTick里放着,所以是批量更新
* 3、在更新的过程中,vue根据这些数据,生成虚拟dom,新的虚拟dom和旧的虚拟dom进行比较,将差异的部分,更新到真实的dom树上
* 4、虚拟dom直接的diff比较算法,vue参考了linux文件系统的文件比较算法
*/
}
})
下发更新,vue会遍历dep里的watch,由watch执行update方法
为什么要引入虚拟dom,在vue1.0时代,没有引入虚拟dom,vue通过watch准确的知道每一个节点的变化,及时更新,但是这样做,更新粒度精确到了每一个数据节点,在大型项目里内存消耗严重;
在vue2.0时代,vue把每一个组件只对应一个watch,组件里的数据变化,只会进一个watch,执行dep里的watch本身是在proceess.nextTick里,会批量更新操作,最后更新到数据会形成一个虚拟dom,然后和旧树进行比较,拿得到的差异,更新到真实dom上.
vue 实现了MVVM 模式
MVVM,说到底还是一种分层架构。它的分层如下:
M:Model 模型
V:View 视图
C:Controller 控制器
VM:ViewModel 视图模型
react
1、react是单向数据流,react在初始化的时候,也会把真实的dom转化成虚拟的dom,vnode是fiber对象节点。
2、react的setState,是通过setState来完成的,setState的更新机制,离不开react的事务机制,Traction对象就是react的事务,Traction整理采用了AOP(装饰者模式)
Traction.before(() => {isBatchingUpdate = true})
Traction.after(() => {isBatchingUpdate = false})
Traction执行的时候,中间的setState处于isBatchingUpdate = true,所以,处理批量更新阶段的state不能立即patch,会放到任务队列里,等都执行完了,触发after,然后,可以真正的更新dom