简单介绍
React是由Facebook常见的js UI框架,它支撑着包括Instagram在内的大多数Facebook网站。其中最大的变化是React推广了Virtual DOM并创造了新语法–JSX,JSX允许开发者在js中书写HTML。
VUE致力解决的问题与React一致,但却提供了另外一套解决方案。Vue使用模版系统而不是JSX,使其对现有应用对升级更加容易。这是因为模版用的就是普通对HTML,听过Vue来整合现有的系统是比较容易的,不需要整体重构。同时Vue更容易学习。还需要说明的是,Vue是由一位开发者维护的,而不像React一样是由Facebook这类大公司维护。
相似之处
- 他们都是JavaScript的UI框架,专注于创造前端的富应用;
- 不同于早期的js框架功能齐全,React与Vue只有框架的骨架,其他的功能如路由,状态管理等是框架分离的组件;
- Vue(2.0版本)与React的其中最大一个相似之处,就是他们使用了Virtual DOM
- 都鼓励组件化
- 看到React和Vue都有props的概念,这是properties的简写。props在组件中是一个特殊的属性,允许父组件往子组件传送数据;
- React和Vue都有自己的构建工具,可以快速搭建开发环境;
- 都有很好的Chrome扩展工具去帮助找出bug;
- 最后一个相似但略有不同之处是他们配套框架的处理方法。相同之处在于,两个框架都专注于UI层,其他功能如路由,状态管理都交由同伴框架进行处理。
React
- 数据流单向
- 推广了Virtual DOM,并创造了新的语法–JSX,允许开发者在js中书写HTML
- 由Facebook这类大公司维护
- props对于子组件来说是必须的,因为它依赖一个单一数据源作为它的状态
- 创建应用使用Create React App(CRA)
- React的react-router和react-redux则由社区成员维护,都不是官方维护的
- 最大的不同是模版的编写
- 需要使用setState方法去更新状态
- 多数情况下,框架内置的状态管理是不足以支撑大型应用的,Redux或Vuex等状态管理方案是必须使用的
Vue
- 数据双向绑定
- 使用的模版是普通的HTML,通过Vue来整合现有的系统是比较容易的,不需要整体重构
- 由一位开发者进行维护的
- 与props略有不同,他们一样是在组件中被定义,但Vue依赖于模版语法,可以通过模版但循环函数更高效地展示传入的数据
- 创建应用则是vue-cli
- Vue的核心团队维护这vue-router和vuex
- 最大的不同是模版的编写
- Vue中state对象并不是必须的,数据由data属性在Vue对象中进行管理
- Vue的解决方案适用于小型应用,但对于大型应用而言不太适合
Virtual DOM
React是通过JSX渲染模版,Vue是通过一种拓展的HTML语法进行渲染,但其实这只是表面现象,毕竟React并不必须依赖JSX。
在深层上,模版原理不同,这才是他们的本质区别,React是在组件js代码中,通过原生js实现模版中的常见语法,比如插值,条件,循环等都是通过js语法实现的,更加纯粹更加原生。而Vue是在和组件js代码分离的单独的模版中,通过指令来实现的,比如条件语句就需要v-if来实现对这一点,这样做法显得有些独特,会把HTML弄的很乱。
举个例子:react的好处–react中render函数只支持闭包的特性的,所以import的组件在render中可以直接调用。但是在Vue中,由于模版中使用的数据都必须挂在this上进行一次中转,所以import一个组件之后,还需要在components中再声明一下,这样显然有些奇怪但又不得不这样做。
Vue(2.0)与React的其中最大一个相似之处,就是他们都使用了一种叫"Virtual DOM"的东西。所谓Virtual DOM基本上说就是它名字的意思:虚拟DOM,DOM树的虚拟表现。它的诞生是基于这么一个概念:改变真实的DOM状态远比改变一个js对象的花销要大得多。
Virtual DOM是一个映射真实DOM的js对象,如果需要改变任何元素的状态,那么是先在Virtual DOM上进行改变,而不是直接改变真实的DOM。当有变化产生时,一个新的Virtual DOM对象会被创建并计算新旧Virtual DOM之间的差别。之后这些差别会应用在真实的DOM上。
例子如下,下面的列表在HTML中的代码
<ul class="list">
<li>item 1</li>
<li>item 2</li>
</ul>
而在js中,可以用对象简单地创造一个针对上面例子的映射
{
type:'ul',
props:{'class':'list'},
children:[
{type:'li',props:{},children:['item 1']},
{type:'li',props:{},children:['item 2']}
]
}
真实的Virtual DOM会比上面的例子更复杂,但它本质上是一个嵌套着数组的原生对象。
当新一项被加进去这个js对象时,一个函数会计算新旧Virtual DOM之间的差异并反应在真实的DOM上。计算差异的算法是高性能框架的秘密所在,React和Vue在实现上有点不同。
Vue宣称可以更快地计算出Virtual DOM的差异,这是由于它在渲染过程中,会跟踪每一个组件的依赖关系,不需要重新渲染整个组件树。
而对React而言,每当应用的状态被改变时,全部子组件都会重新渲染。当然,着可以通过shouldComponentUpdate这个生命周期方法来进行控制,但Vue将此视为默认的优化。
小结:如果你的应用中,交互复杂,需要处理大量UI变化,那么使用Virtual DOM是一个好主意。如果你更新元素并不频繁,那么Virtual DOM并不一定适用,性能很可能还不如直接操作DOM。
组件化
React和Vue都鼓励组件化应用。这本质上说,是建议你将你的应用分拆成一个个功能明确的模块,每个模块之间可以通过合适的方式互相联系。
Vue中由三种方式可以实现组件通信:
父组件通过props向子组件传递数据或者回调,虽然可以传递回调,但是一般只传数据;
子组件通过事件向父组件发送消息;
通过新增的provide/inject来实现父组件向子组件注入数据,可以跨越多个层级。
React中也有对应的三种方式:
父组件通过props可以向子组件传递数据或者回调;
可以通过context进行跨层级的通信,这其实跟provide/inject起到的作用差不多。React本身并不支持自定义事件,而Vue中子组件向父组件传递消息有两种方式:事件和回调函数,但Vue更倾向于使用事件。在React中都是使用回调函数的,这可能是他们二者最大的区别。
Props
React和Vue都有Props概念,这是properties的简写。props在组件中是一个特殊的属性,允许父组件往子组件传送数据。
Object.key(this.state.pastadishes).map(key=>
<PastaItem index={key} key={key} details={this.state.pastadishes[key]} addToOrder={this.addToOrder} orders={this.state.orders[key]} />
)
上面JSX库组件中,index,key,details,orders与addToOrder都是props,数据会被下传到子组件PastaItem中去。
在React中,这是必须的,它依赖一个"单一数据源"作为它的"状态"
而在Vue中,props略有不同,他们一样是在组件中被定义,但Vue依赖于模版语法,可以通过模版的循环函数更高效地展示传入的数据。
<pasta-item v-for="(item,key) in samplePasta" :item="item" :key="key" @order="handleOrder(key)"></pasta-item>
这是模版的实现,但这代码完全能工作,然而在React中展现相同的数据会更麻烦一点。
构建工具
React和vue都有自己的构建工具,你可以使用它快速搭建开发环境。React可以使用Create React App,而Vue对应的则是vue-cli。两个工具都能让你得到一个根据最佳实践设置的项目模版。
由于CRA有很多选项,使用起来会稍微麻烦一点。这个工具会逼迫你使用Webpack和Babel。而vue-cli则有模版列表可选,能按需创建不同的模版,使用起来更灵活一点。
事实上,两个工具都非常好用,都能为你建立一个好环境。
配套框架
Vue与React最后一个相似但略有不同之处是他们配套框架的处理方法。相同之处在于,两个框架都专注于UI层,其他的功能如路由,状态管理等都交由同伴框架进行处理。
而不同之处是在于他们如何关联它们各自的配套框架。Vue的核心团队维护着vue-router和vuex,他们都是作为官方推荐的存在。而React的react-router和react-redux则是由社区成员维护,他们都不是官方维护的。
框架本质不同
Vue本质是MVVM框架,由MVC发展而来;
React是前端组件化框架,由后端组件化发展而来。
模版 vs JSX
React与vue最大的不同是模版的编写。Vue鼓励你去写近似常规HTML的模版。写起来很接近标准HTML元素,只是多了一些属性。
这些属性也可以被使用在单文件组件中,尽管它需要在构建时将组件转换为合法的js和HTML。
Vue鼓励去使用HTML模版去进行渲染,使用相似于angular风格的方法去输出动态的内容。因此,通过把原有的模版整合成新的Vue模版,Vue很容易提供旧的应用的升级,这也让新来者很容易适应他的语法。
另一方面,React推荐你所有的模版通用js的语法扩展–JSX书写。
React/JSX乍看之下,觉得非常啰嗦,但使用js而不是模版开开发的,赋予来开发者许多编程能力。
JSX只是js混合着XML语法。然而一旦你掌握来它,它使用起来会让你感到愉快。
而相反的观点是Vue的模版语法取出来往视图/组件中添加逻辑的诱惑,保持了关注点分离。
值得一提的是与React一样,Vue在技术上也支持render函数和JSX,但只是不是默认而已。
状态管理 VS 对象属性
如果对React熟悉,就会知道应用中的状态是React关键的概念。也有一些配套框架被设计为管理一个大的state对象,如Redux。此外,state对象在React应用中是不可变的,意味着它不能被直接改变,在React中你需要使用setState方法去改变状态。
在Vue中,state对象并不是必须的,数据由data属性在Vue对象中进行管理。
而在Vue中,则不需要使用如setState之类的方法去改变它的状态,在Vue对象中,data参数就是应用中数据的保存者。
从实现原理来说,最大的区别是两点:Redux使用的是不可变数据,而Vuex的数据是可变的,因此,Redux每次都是用新的state替换旧state,而Vue是直接修改。Redux在检测数据变化的适合,是通过Diff的方式比较差异的。而Vuex其实和Vue的原理一样,是通过getter/setter来比较的,这两点的区别,也是因为react和vue的设计理念不同。React更偏向于构建稳定大型的应用,非常的科班化。相比之下,Vue更偏向于简单迅速的解决问题,更灵活,不那么严格遵循条条框框。因此也会给人一种大型项目用React,小型项目用Vue的感觉。
对于管理大型应用中的状态这一话题而言,vue的作者说过,Vue的解决方案适用于小型应用,但对于大型应用而言不太适合。
多数情况下,框架内置的状态管理是不足以支撑大型应用的,Redux或Vuex等状态管理方案是必须使用的。