hawx1993 / tech-blog

📦My personal tech blog,not regularly update
http://sf.gg/u/trigkit4/articles
339 stars 30 forks source link

react和vue 深入对比 #17

Open hawx1993 opened 7 years ago

hawx1993 commented 7 years ago

前言

react和Vue我都使用过,react项目是团队参与的一个后台管理系统,Vue项目则是个人独立开发的。这里记录下两个框架的一些异同之处吧

virtual DOM

Vue2.0 引入了virtual DOM的概念,我们知道,改变真实的DOM状态远比改变一个JavaScript对象的花销要大得多。Vue宣称可以更快地计算出Virtual DOM的差异,这是由于它在渲染过程中,会跟踪每一个组件的依赖关系,不需要重新渲染整个组件树。而对于React而言,每当应用的状态被改变时,全部子组件都会重新渲染。当然,这可以通过shouldComponentUpdate这个生命周期方法来进行控制,但Vue将此视为默认的优化。与 DOM 操作相比,Virtual Dom 是基于 JavaScript 计算,所以开销会小很多。

在 Vue2 里,就是通过 Render 函数来实现 Virtual Dom 的。

组件与数据流

react和Vue都鼓励组件化,在Vue中,你可以使用单文件组件,将样式,模板,和逻辑写在一起;

而react也是可以的,在react中,js和jsx杂糅在一起,被写入同一个组件中

React中实现组件有两种方式,一种是createClass 方法,另一种是通过ES2015的思想 类继承React.Component 来实现。

//creatClass
import React from 'react';

export default React.createClass({
  constructor(){
    super()
  }
   render() {
     return (
       <div>hello react</div>
     )
   }
})

//类继承
import React from 'react';

export default class Comment extends React.Component{
  render() {
    return (
      <divclassName="comment">
        <span>{ this.props.author }</span>
        <span>{ this.props.date }</span>
        <div>{ this.props.children }</div>
      </div>
    )
  }
}

react和Vue组件中,都存在一个props属性的概念,允许父组件往子组件传送数据,而且都是单向流动,不可逆向流动

在React中,父与子之间的数据通信是通过props属性就行传递的; 而子与父之间的数据通信可以通过父组件定义事件,子组件触发父组件中的事件时,通过实参的形式来改变父组件中的数据来通信;

React是单向数据流,从父节点传递到子节点(通过props)。Vue则实现了双向数据绑定,vue通过Object.defineProperty() 定义数据的 set和get,从而实现了双向数据绑定。

组件生命周期

image

关于vue的生命周期,可以看我之前这篇文章:也谈Vue2.0生命周期和路由

工具

react方面提供了creat-react-app,而Vue则提供了Vue-cli,vue-cli通过命令行的方式,提供了多套构建工具的模板。

对于浏览器扩展,react提供了react-devtools,vue也有vue-devtools。

配套框架

配套框架方面,vue核心团队提供了vue-router和vuex,react的react-router和react-redux则是由社区成员维护,react-redux则是基于redux的react版本,它们都不是官方维护的。

模板与jsx

React与Vue最大的不同是模板的编写。vue的template是写在单文件组件中的,使用了基于 HTML 的模版语法,Vue鼓励你去使用HTML模板去进行渲染:

ul class="unstyled">
  <li v-for="todo in todoList.todos">
    <input type="checkbox" ng-model="todo.done">
    <span class="done-{{todo.done}}">{{todo.text}}</span>
  </li>
</ul>

那么,模板引擎有哪些缺点,才使得react放弃了传统的模板引擎,而自己重新造轮子,发明了jsx呢,在我看来,模板引擎的缺点有这么几个方面:

react方面,直接放弃了模板而发明了JSX,通过render渲染方法,将 JSX + inline style + DOM写在了一起:

let lis = this.todoList.todos.map(function (todo) {
  return  (
    <li>
      <input type="checkbox" checked={todo.done}>
      <span className={'done-' + todo.done}>{todo.text}</span>
    </li>
  );
});
let ul = (
  <ul class="unstyled">
    {lis}
  </ul>
);

值得一提的是,与React一样,Vue在技术上也支持render函数和JSX,但只是不是默认的而已。

状态管理

状态(state)在react中是关键的概念,它是不可变的,在React中你需要使用setState()方法去更新状态。

而在vue中,state对象并不是必须的,数据由data属性在Vue对象中进行管理。

<template>
<div class='container'>
  <p>{{ name }}</p>
</div>
</template>
export default {
  name: 'app',
  data() {
    return {
      name: 'trigkit4'
    }
  }
}

而在Vue中,则不需要使用如setState()之类的方法去改变它的状态,在Vue对象中,data方法就是应用中数据的保存者。

react和vue方面,当非父子组件之间嵌套过深的时候都建议使用状态管理来维护数据的变化。

react则推荐使用flux,貌似react-redux更为强大,vue方面,则是提供了vuex,

生态方面

创建原生应用方面,react-naive则处于领先地位,vue也与阿里合作,开发了vue版的react-native

react有ant-design,vue则有element,iview等。

其他

Vue.js从React那里借鉴了组件化、prop、单向数据流、性能、虚拟渲染,并意识到状态管理的重要性。

Vue.js从Angular那里借鉴了模板,并赋予了更好的语法,以及双向数据绑定(在单个组件里)。

c446984928 commented 7 years ago

写得很不错啊!谢谢

soulSingerK commented 6 years ago

vue 并没有实现真正的双向绑定,所谓的双向绑定无非是结合onchange事件实现的语法糖

zhangruinian commented 6 years ago

你好 请问front-end-interviewer-question去哪可以看呀

rt-zhangxuefei commented 6 years ago

两个框架我用了,写了点体会 http://zhangxuefei.site/p/2068