探索「Vue」与「React」的区别

2,025 阅读5分钟

探索「Vue」与「React」的区别

Vue和React都是目前最流行、生态最好的前端框架之一,之所以用“与”字来做标题,也是为了避免把他们放在对立面。毕竟框架本身没有优劣之分,只有适用之别,选择符合自身业务场景、团队基础的技术才是我们最主要的目的。

本文希望通过对比两个框架在使用上的区别,能使只用其中一个框架进行开发的开发者快速了解和运用另一个框架,已应对不同技术栈的需求,无论你是为了维护老系统还是为了适应新的生态(React-Native)。

那我们现在就从下面这几个步骤来分别聊聊Vue和React的区别:

react和vue都是做组件化的,整体的功能都类似,但是他们的设计思路是有很多不同的。使用react和vue,主要是理解他们的设计思路的不同。

1.数据是不是可变的

react整体是函数式的思想,把组件设计成纯组件,状态和逻辑通过参数传入,所以在react中,是单向数据流,推崇结合immutable来实现数据不可变。react在setState之后会重新走渲染的流程,如果shouldComponentUpdate返回的是true,就继续渲染,如果返回了false,就不会重新渲染,PureComponent就是重写了shouldComponentUpdate,然后在里面作了props和state的浅层对比。

而vue的思想是响应式的,也就是基于是数据可变的,通过对每一个属性建立Watcher来监听,当属性变化的时候,响应式的更新对应的虚拟dom。

总之,react的性能优化需要手动去做,而vue的性能优化是自动的,但是vue的响应式机制也有问题,就是当state特别多的时候,Watcher也会很多,会导致卡顿,所以大型应用(状态特别多的)一般用react,更加可控。

2.生命周期

react:

componentWillMount:组件初始化时只调用,以后组件更新不调用,整个生命周期只调用一次,此时可以修改state。下一个版本可能会被废弃。

render:react最重要的步骤,创建虚拟dom,进行diff算法,更新dom树都在此进行。此时就不能更改state了。

componentDidMount:组件渲染之后调用,只调用一次。

componentWillReceiveProps:组件初始化时不调用,组件接受新的props时调用。

componentWillUnmount:组件将要卸载时调用,一些事件监听和定时器需要在此时清除。

componentWillUndate:组件更新结束之前执行,在初始化render时不执行。

componentDidUndate:组件更新结束之后执行,在初始化render时不执行

注意:componentDidMount 里面 setState 导致组件更新,组件更新后会执行 componentDidUpdate,此时你又在 componentDidUpdate 里面 setState 又会导致组件更新,造成成死循环了,如果要避免死循环,需要谨慎的在 componentDidUpdate 里面使用 setState

vue:

beforeCreate( 创建前 )

在实例初始化之后,数据观测和事件配置之前被调用,此时组件的选项对象还未创建,el 和 data 并未初始化,因此无法访问methods, data, computed等上的方法和数据。

created ( 创建后 )

实例已经创建完成之后被调用,在这一步,实例已完成以下配置:数据观测、属性和方法的运算,watch/event事件回调,完成了data 数据的初始化,el没有。 然而,挂在阶段还没有开始, $el属性目前不可见,这是一个常用的生命周期,因为你可以调用methods中的方法,改变data中的数据,并且修改可以通过vue的响应式绑定体现在页面上,,获取computed中的计算属性等等,通常我们可以在这里对实例进行预处理,也有一些童鞋喜欢在这里发ajax请求,值得注意的是,这个周期中是没有什么方法来对实例化过程进行拦截的,因此假如有某些数据必须获取才允许进入页面的话,并不适合在这个方法发请求,建议在组件路由钩子beforeRouteEnter中完成

beforeMount

挂在开始之前被调用,相关的render函数首次被调用(虚拟DOM),实例已完成以下的配置: 编译模板,把data里面的数据和模板生成html,完成了el和data 初始化,注意此时还没有挂在html到页面上。

mounted

挂在完成,也就是模板中的HTML渲染到HTML页面中,此时一般可以做一些ajax操作,mounted只会执行一次。

beforeUpdate

在数据更新之前被调用,发生在虚拟DOM重新渲染和打补丁之前,可以在该钩子中进一步地更改状态,不会触发附加地重渲染过程

updated(更新后)

在由于数据更改导致地虚拟DOM重新渲染和打补丁只会调用,调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作,然后在大多是情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环,该钩子在服务器端渲染期间不被调用

beforeDestrioy (销毁前)

在实例销毁之前调用,实例仍然完全可用,

这一步还可以用this来获取实例, 一般在这一步做一些重置的操作,比如清除掉组件中的定时器 和 监听的dom事件 destroyed(销毁后)

在实例销毁之后调用,调用后,所以的事件监听器会被移出,所有的子实例也会被销毁,该钩子在服务器端渲染期间不被调用

3.模板和JSX

react:

HTML 语言直接写在 JavaScript 语言之中,不加任何引号,这就是 JSX 的语法,它允许 HTML 与 JavaScript 的混写

vue:

Vue.js 使用了基于 HTML 的模版语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。Vue.js 的核心是一个允许你采用简洁的模板语法来声明式的将数据渲染进 DOM 的系统。

4.组件作用域内的 CSS

对于Vue 来说,

设置样式的默认方法是单文件组件里类似 style 的标签。 单文件组件让你可以在同一个文件里完全控制 CSS,将其作为组件代码的一部分。

<style scoped>
  .container{
      display:flex;
  }
</style>

这个可选 scoped 属性会自动添加一个唯一的属性 (比如 data-v-8123) 为组件内 CSS 指定作用域。

对于React来说,

语法不太一样,React设置class是用className字段,而设置css是使用对象的形式,当然,一般还是引入外部的css(经过编译的sass或者less文件)比较合适。

5.组件传值

react:

父到子,父组件自定义属性,子通过props来获取父的属性值

子到父,在父组件绑定callbackParent={this.onChildChanged},在子组件利用this.props.callbackParent(newState),触发了父级的的this.onChildChanged方法,进而将子组件的数据(newState)传递到了父组件。

这样做其实是依赖 props 来传递事件的引用,并通过回调的方式来实现

onChildChanged: function (newState) {
    this.setState({
      checked: newState
    });
  },

vue:

1.父组件传递数据给子组件

父组件数据如何传递给子组件呢?可以通过props属性来实现

父组件:

<parent>
    <child :child-msg="msg"></child>  //这里必须要用 - 代替驼峰
</parent>
data(){
    return {
        msg: [1,2,3]
    };
}

子组件通过props来接收数据:

props: ['childMsg']

2.子组件与父组件通信

子组件:

<template>
    <div @click="testClick"></div>
</template>
methods: {
    testClick() {
        this.$emit('test','123'); //主动触发test方法,'123'为向父组件传递的数据
    }
}

父组件:

<div>
    <child @test="change" :msg="msg"></child>  //监听子组件触发的test事件,然后调用change方法
</div>
methods: {
    change(msg) {
        this.msg = msg;  // msg: 123
    }
}

6.规模

Vue 和 React 都提供了强大的路由来应对大型应用。React 社区在状态管理方面非常有创新精神 (比如 Flux、Redux),而这些状态管理模式甚至 Redux 本身也可以非常容易的集成在 Vue 应用中。实际上,Vue 更进一步地采用了这种模式 (Vuex),更加深入集成 Vue 的状态管理解决方案 Vuex 相信能为你带来更好的开发体验。

两者另一个重要差异是,Vue 的路由库和状态管理库都是由官方维护支持且与核心库同步更新的。React 则是选择把这些问题交给社区维护,因此创建了一个更分散的生态系统。但相对的,React 的生态系统相比 Vue 更加繁荣。

总结

react整体的思路就是函数式,所以推崇纯组件,数据不可变,单向数据流,当然需要双向的地方也可以做到,比如结合redux-form,而vue是基于可变数据的,支持双向绑定。react组件的扩展一般是通过高阶组件,而vue组件会使用mixin。vue内置了很多功能,而react做的很少,很多都是由社区来完成的,vue追求的是开发的简单,而react更在乎方式是否正确。

下一回将带领大家来了解react中所没有的vue属性!