Vue和React的区别【个人观点】

3,931 阅读5分钟

Vue

Vue是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合

React

与 Vue 不同,react 库是由 Facebook 创建的。最初是为了 Facebook 广告流量管理创建的。那时 Facebook 遇到了维护和编码方面的问题。它以动态创建和交互式 UI 的能力而闻名。

监听数据变化的实现原理的不同之处

Vue 通过 getter/setter 以及一些函数的劫持,能精确知道数据变化,不需要特别的优化就能达到很好的性能

React 默认是通过比较引用的方式进行的,如果不优化(PureComponent/shouldComponentUpdate)可能导致大量不必要的VDOM的重新渲染

为什么 React 不精确监听数据变化呢?这是因为 Vue 和 React 设计理念上的区别,Vue 使用的是可变数据,而React更强调数据的不可变。所以应该说没有好坏之分,Vue更加简单,而React构建大型应用的时候更加鲁棒。

因为一般都会用一个数据层的框架比如 Vuex 和 Redux,所以这部分不作过多解释,在最后的 vuex 和 redux的区别 中也会讲到。

核心思想对比

vue与react都推崇组件式的开发理念,但是在设计的核心思想上有很大差别。

Vue的核心思想

vue的整体思想仍然是拥抱经典的html(结构)+css(表现)+js(行为)的形式,vue鼓励开发者使用template模板,并提供指令供开发者使用(v-if、v-show、v-for等等),因此在开发vue应用的时候会有一种在写经典web应用(结构、表现、行为分离)的感觉。另一方面,在针对组件数据上,vue2.0通过Object.defineProperty对数据做到了更细致的监听,精准实现组件级别的更新。

React的核心思想

react整体上是函数式的思想,组件使用jsx语法,all in js,将html与css全都融入javaScript,jsx语法相对来说更加灵活,我一开始刚转过来也不是很适应,感觉写react应用感觉就像是在写javaScript。当组件调用setState或props变化的时候,组件内部render会重新渲染,子组件也会随之重新渲染,可以通过shouldComponentUpdate或者PureComponent可以避免不必要的重新渲染(个人感觉这一点上不如vue做的好)。

数据管理(Vue的props、data vs React的props、state)

组件数据管理通常包含2部分,来自父组件的数据props与自身的数据。

vue与react中的props都是单向数据流的,父级prop的更新会向下流动到子组件中,但是反过来则不行。prop可以是数组或对象,用于接收来自父组件的数据。

vue

props

vue中的props支持传递静态或动态props,静态props一般传递字符串。

<blog-post title="My journey with Vue"></blog-post>

静态prop传递布尔值true可以这样写,传值false仍然需要使用动态prop传值。

<blog-post disabled></blog-post>

动态赋值使用v-bind,可以简写为:。

<blog-post v-bind:title="tile"></blog-post>
// 简写形式
<blog-post :title="tile"></blog-post>

动态prop常用来传递对象、数组、布尔值(false值,true值可以直接传属性)等。

<blog-post :title="post.title + ' by ' + post.author.name"></blog-post>

data

vue中使用data来管理组件的数据,vue 将会递归将 data 的属性转换为 getter/setter,从而让 data 的属性能够响应数据变化。对象必须是纯粹的对象 (含有零个或多个的 key/value 对)。一旦观察过,不需要再次在数据对象上添加响应式属性。因此推荐在创建实例之前,就声明所有的根级响应式属性。

当一个组件被定义,data必须声明为返回一个初始数据对象的函数。

export default {
  name: 'NewComponent',
  data() {
    return {
      name: 'xxx',
      age: 12
    }
  }
}

当需要在组件内部修改数据时,可以直接通过vue实例修改:

methods: {
    changeName() {
      this.name = 'new Name';
    }
  }

react

props

react中的props与vue一样可以传递静态或动态props,静态props一般传递字符串,在函数组件和class组件都可以使用props,函数组件使用props参数获取父组件传下来的props。

函数组件获取props

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}
const element = <Welcome name="Sara" />;

class组件使用this.props获取组件props

class Welcome extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    const { name } = this.props;
    return <div>{name}</div>;
  }
}

动态props:

<Welcome name={name} />

class组件state

class组件在构造函数(constructor)中定义组件内数据(state),修改数据必须通过setState修改,不能直接修改state,这点非常重要。

class组件使用state

class Welcome extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      name: 'xx'
    };
    this.changeName = this.changeName.bind(this);
  }
  changeName() {
    this.setState({
      name: 'new name'
    });
  }
  render() {
    const { name } = this.state;
    return <div onClick={this.changeName}>{name}</div>;
  }
}

数据流的不同

image.png

在Vue1.0中我们可以实现两种双向绑定:在父子组件之间props 可以双向绑定,组件与DOM之间可以通过 v-model 双向绑定

在 Vue2.x 中去掉了第一种,也就是父子组件之间不能双向绑定了(但是提供了一个语法糖自动帮你通过事件的方式修改),并且 Vue2.x 已经不鼓励组件对自己的 props 进行任何修改了。
所以现在我们只有 组件 <--> DOM 之间的双向绑定这一种。

然而 React 从诞生之初就不支持双向绑定,React一直提倡的是单向数据流,他称之为 onChange/setState() 模式。

不过由于我们一般都会用 Vuex 以及 Redux 等单向数据流的状态管理框架,因此很多时候我们感受不到这一点的区别了。