React和Vue比较

时间:2021-2-20 作者:admin

React和Vue都是现在比较流行的js框架,两者存在一定的异同,各有优缺点,分析两者的异同,可以从他们的设计思想出发。


1.数据驱动

两者都是数据驱动视图,但是实现方式还是有所差异的。

React

要想了解数据驱动视图的过程,首先要了解react的渲染过程

  1. 编写:组件都是继承自React.Component(函数式组件除外),组件内部的视图模板文件则采用jsx的语法进行编写
  2. 编译:将我们编写的组件实例编译成一个个的虚拟dom节点(本质就是json对象)
  3. 挂载:将虚拟dom节点编译成真实dom,并挂载到界面

React中数据驱动视图是通过setState来实现的,setState并不是直接导致真实dom的改变,它首先映射到虚拟的dom节点,虚拟dom节点的挂载导致页面视图的变化。

从流程上看,似乎多此一举,直接操作dom节点改变数据不是更直接,为什么要绕弯操作虚拟dom?首先dom操作的会导致浏览器的重绘重排,性能开销比较大,直接操作dom就和原生的js/jquery项目类似了。当我们在一个方法中出现了多次数据变化时,每次都要操作dom很浪费性能。有了虚拟dom后,把多次的数据变化先映射到虚拟dom中,最后进行一次挂载,相当于只操作了一次真实dom,有效的降低了性能开销。

Vue

要了解vue的数据驱动视图原理,就要了解Object.defineProperty,vue就是以此为基础实现的数据驱动。vue利用Object.defineProperty的“劫持”作用,实现了对data对象中属性改变时的监听

let data  = {name: 'tom', age: 10}
Object.defineProperty(data,'name',{
    get: function () {
        console.log('获取对象属性')
    },
    set: function () {
        console.log('设置对象属性')
    }
})
data.name  // 读取对象属性时, 会走进get方法
data.name = 'jack' // 设置对象属性时,会走进set方法 

如此,对data对象的属性改变就会被监听到,从而实现“劫持作用”。vue的实现数据驱动的基本工作流程是这样的:

  1. data函数中返回的对象中属性递归,每个属性都会注册Object.defineProperty方法,这样每个属性的改变都可以被监听到。这也是为什么vue可以设置状态对象的二级属性,而react不可以。
// vue 
data () {
    return {
        person: {name: 'tom', age: 10}
    }
}
// this.person.name = 'jack'

// react
state = {
    person: {name: 'tom', age: 10}
}
// this.setState({person: {name: 'jack', age: 10}})
  1. 每个组件都有一个watcher观察者实例,类似于react组件中对应的updater实例,它会在组件渲染的过程中把“接触”过的数据属性记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。

这个过程最为关键的点在依赖项的setter触发时通知watcher,但watcher并不会马上触发关联的组件进行重新渲染,Vue在更新 DOM 时是异步执行的。

<template>
    <div ref="name">{{name}}</div>
    <button @changeName="changeName">click</button>
</template>
<script>
    export default {
        data () {
            name: 'tom'
        },
        methods: {
            changeName () {
                this.name = 'jack'
                console.log(this.name)  // jack
                console.log(this.$refs.name.innerHTML) // tom
            }
        }
    }
</script>

点击按钮时,可以发现data中的属性更新了,页面上没有更新,证明了上述观点。那什么时候更新呢?这个道理和react一样,为了防止多次更新dom,提高效率,setState后所有改变的状态都收集到updater,页面ui和state状态数据始终保持一致,组件更新时state和ui是一致更新的,但和vue在表现手法上还是有区别的,vue则是直接修改了data中的状态,但暂时先不更新页面,当方法结束后,再根据状态更新页面。

小结:

简而言之,react需要借助setState来实现数据驱动视图,vue可以通过直接对属性赋值的方式进行数据驱动视图操作。


2.优化

两者都采用了虚拟dom,也各自有自身的diff算法,这里暂时不讨论具体 diff算法实现。

React

在 React 应用中,当某个组件的状态发生变化时,它会以该组件为根,重新渲染整个组件子树。这势必会带来一定程度上的不必要的子组件重新渲染,如果你想要避免这些不必要的重新渲染,就需要人为的去使用react提供的类组件PureComponent,或者可以在组件中使用shouldComponentUpdate来阻止不必要的渲染。

Vue

在 Vue 应用中,组件的依赖是在渲染过程中自动追踪的,所以系统能精确知晓哪个组件确实需要被重渲染。类似于每个组件都自动获取了shouldComponentUpdate方法,不需要开发者考虑这方面性能优化的问题,能够更专注于业务开发。

小结:

vue提供的方式对于开发者而言可能更为友好,更为稳定和安全。react的方式给到了开发者足够的自由度,可以让你自由的去决定什么组件需要重新渲染,什么组件不需要重新渲染。


3.语法

React

上文有提到react是使用jsx语法进行编写的,这是因为react 认为现在浏览器追求的js,css,html 这三种文件分工协作的方式效率低下,他认为js,css,html 应该是一个整体,而不是像现在这样分的这么清楚,协作的时候造成了很多麻烦,所以他们推荐一个组件的所有代码都写在一个jsx当中,这样更有利于组件化开发。jsx 本身也是js的一种扩展,可以完全写js 没问题,基本上一个有状态的组件就是一个类。在一个固定的render方法里返回标签,标签和数据逻辑全都耦合在一个类里面。另外,个人认为,jsx在一定程度上也降低了开发门槛,部分开发者可能只需要专注于js本身就行,不需要了解其他过多的语法就能进行开发了。

Vue

vue是基于template语法进行开发的,和本身的html十分相似,vue的核心是一个允许你采用简洁的模板语法来声明式的将数据渲染进 DOM 的系统。如果你本身拥有一些前端知识的话,vue的上手将会十分轻松。

小结:

对于语法来说,个人认为两者没有明显的优劣势。就本人而言,由于是先接触的react,所以可能更习惯于jsx语法。


总结:

react和vue对比,两者都有各自的优缺点,当然,区别不止上文提到的这些。例如:生态环境,还有状态管理,路由管理等工具,开发模式等等。对于本人来说,直观的感受就是,react更像是提供了一系列的工具,应用的成熟度或者稳定性等更大程度上依赖于开发者的水平。而vue帮开发者做了大量的工作,你只要遵循vue提供的规范,就能很好的开发出一套相对稳定的应用。

声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。