Vue与React的对比
Vue.js与React.js从某些反面来讲很类似,经过两个框架的学习,有时候对一些用法会有一点思考,为加深学习的思索,特翻阅了两个文档,从如下各方面进行了对比,加深了对这两个框架的认知。css
1.数据绑定
1.1 Vue中有关数据绑定的部分
- vue是双向绑定, Vue.js 最核心的功能有两个,一是响应式的数据绑定系统,二是组件系统。所谓双向绑定,指的是vue实例中的data与其渲染的DOM元素的内容保持一致,不管谁被改变,另外一方会相应的更新为相同的数据。这是经过设置属性访问器实现的。
- 在vue中,与数据绑定有关的有 插值表达式、指令系统、*Class和Style、事件处理器和表单空间、ajax请求和计算属性
1.1.1插值表达式
插值和指令又称为模板语法
- 数据绑定最多见的形式就是使用“Mustache”语法 (双大括号) 的文本插值
- Mustache 语法不能做用在 HTML 特性上,遇到这种状况应该使用 v-bind 指令html
1.1.2 指令
-
vue中的指令很方便,指令 (Directives) 是带有 v- 前缀的特殊属性。指令属性的值预期是单个 JavaScript 表达式 (v-for 是例外状况,稍后咱们再讨论)。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地做用于 DOM。前端
-
vue中的12个指令: v-bind,v-once,v-model,v-text,v-html,v-on,v-if,v-else,v-show,v-for,v-pre,v-clock
vue
1.1.3 class与style绑定
- 数据绑定的一个常见需求是操做元素的 class 列表和它的内联样式。由于它们都是属性 ,咱们能够用v-bind 处理它们:只须要计算出表达式最终的字符串。不过,字符串拼接麻烦又易错。所以,在 v-bind 用于 class 和 style 时,Vue.js 专门加强了它。表达式的结果类型除了字符串以外,还能够是对象或数组。
- 对象语法
- 咱们能够传给 v-bind:class 一个对象,以动态地切换 class
- 数组语法
- 咱们能够把一个数组传给 v-bind:class,以应用一个 class 列表:
<div v-bind:class="[activeClass, errorClass]"></div>
1.1.4 条件渲染和列表渲染
- v-if条件渲染一组数
- 咱们用 v-for 指令根据一组数组的选项列表进行渲染。v-for 指令须要使用 item in items 形式的特殊语法,items 是源数据数组而且 item 是数组元素迭代的别名。
1.1.5 事件处理器
- 经过v-on给元素注册事件
- 使用 v-on 有几个好处:
- 扫一眼 HTML 模板便能轻松定位在 JavaScript 代码里对应的方法。
- 由于你无须在 JavaScript 里手动绑定事件,你的 ViewModel 代码能够是很是纯粹的逻辑,和 DOM 彻底解耦,更易于测试。
- 当一个 ViewModel 被销毁时,全部的事件处理器都会自动被删除。你无须担忧如何本身清理它们。
1.1.6 表单控件
- v-model在表单控件元素上建立双向数据绑定
- 它会根据控件类型自动选取正确的方法来更新元素。
1.1.7 计算属性
- 在Vue中引入了计算属性来处理模板中放入太多的逻辑会让模板太重且难以维护的问题,这样不但解决了上面的问题,并且也同时让模板和业务逻辑更好的分离。
- 简单来讲,假如data里面有属性a=1,而后你须要一个变量跟着a变化,例如b=a+1,那么就须要用到计算属性,Vue实例的computed属性中,设置b为其属性,其表现为一个函数,返回值是b的值。
1.1.8 ajax数据请求
注: 关于vue的数据双向绑定和单向数据流
-
Vue 的依赖追踪是【原理上不支持双向绑定,v-model 只是经过监听 DOM 事件实现的语法糖】react
-
vue的依赖追踪是经过 Object.defineProperty 把data对象的属性所有转为 getter/setter来实现的;当改变数据的某个属性值时,会触发set函数,获取该属性值的时候会触发get函数,经过这个特性来实现改变数据时改变视图;也就是说只有当数据改变时才会触发视图的改变,反过来在操做视图时,只能经过DOM事件来改变数据,再由此来改变视图,以此来实现双向绑定ios
- 双向绑定是在同一个组件内,将数据和视图绑定起来,和父子组件之间的通讯并没有什么关联;
- 组件之间的通讯采用单向数据流是为了组件间更好的解耦,在开发中可能有多个子组件依赖于父组件的某个数据,假如子组件能够修改父组件数据的话,一个子组件变化会引起全部依赖这个数据的子组件发生变化,因此vue不推荐子组件修改父组件的数据,直接修改props会抛出警告
1.2 react没有数据双向绑定
- react是单向数据流
- react中经过将state(Model层)与View层数据进行双向绑定达数据的实时更新变化,具体来讲就是在View层直接写JS代码Model层中的数据拿过来渲染,一旦像表单操做、触发事件、ajax请求等触发数据变化,则进行双同步
1.2.1事件处理
1.2.2 条件渲染
- React 中的条件渲染和 JavaScript 中的一致,使用 JavaScript 操做符 if 或条件运算符来建立表示当前状态的元素,而后让 React 根据它们来更新 UI。
- 你能够经过用花括号包裹代码在 JSX 中嵌入任何表达式 ,也包括 JavaScript 的逻辑与 &&,它能够方便地条件渲染一个元素。之因此能这样作,是由于在 JavaScript 中,true && expression 老是返回 expression,而 false && expression 老是返回 false。所以,若是条件是 true,&& 右侧的元素就会被渲染,若是是 false,React 会忽略并跳过它。
- 条件渲染的另外一种方法是使用 JavaScript 的条件运算符 condition ? true : false。
1.2.3 列表渲染
- 你能够经过使用{}在JSX内构建一个元素集合,使用Javascript中的map()方法循遍历数组
- Keys能够在DOM中的某些元素被增长或删除的时候帮助React识别哪些元素发生了变化。所以你应当给数组中的每个元素赋予一个肯定的标识。一个元素的key最好是这个元素在列表中拥有的一个独一无二的字符串。一般,咱们使用来自数据的id做为元素的key。
1.2.4 表单操做
- HTML表单元素与React中的其余DOM元素有所不一样,由于表单元素生来就保留一些内部状态。
- 当用户提交表单时,HTML的默认行为会使这个表单会跳转到一个新页面。在React中亦是如此。但大多数状况下,咱们都会构造一个处理提交表单并可访问用户输入表单数据的函数。实现这一点的标准方法是使用一种称为“受控组件”的技术。其值由React控制的输入表单元素称为“受控组件”。
this.setState({value: event.target.value});
- 当你有处理多个受控的input元素时,你能够经过给每一个元素添加一个name属性,来让处理函数根据 event.target.name的值来选择作什么。
1.2.5 状态提高
- 在React中,状态分享是经过将state数据提高至离须要这些数据的组件最近的父组件来完成的。这就是所谓的状态提高。
this.props.xxx
- 在React应用中,对应任何可变数据理应只有一个单一“数据源”。一般,状态都是首先添加在须要渲染数据的组件中。此时,若是另外一个组件也须要这些数据,你能够将数据提高至离它们最近的父组件中。你应该在应用中保持 自上而下的数据流,而不是尝试在不一样组件中同步状态。
2.组件化以及组件数据流
2.1 react中的组件及数据流
- React是单向数据流,数据主要从父节点传递到子节点(经过props)。若是顶层(父级)的某个props改变了,React会重渲染全部的子节点。
- react中实现组件有两种实现方式,一种是createClass方法,另外一种是经过ES2015的思想类继承React.Component来实现
- 在React应用中,按钮、表单、对话框、整个屏幕的内容等,这些一般都被表示为组件。
- React推崇的是函数式编程和单向数据流:给定原始界面(或数据),施加一个变化,就能推导出另一个状态(界面或者数据的更新)
- 组件能够将UI切分红一些的独立的、可复用的部件,这样你就只需专一于构建每个单独的部件。组件从概念上看就像是函数,它能够接收任意的输入值(称之为“props”),并返回一个须要在页面上展现的React元素。
1. Props的只读性
- 不管是使用函数或是类来声明一个组件,它决不能修改它本身的props。
- 全部的React组件必须像纯函数那样使用它们的props。
props与State的区别
- props是property的缩写,能够理解为HTML标签的attribute。不可使用this.props直接修改props,由于props是只读的,props是用于整个组件树中传递数据和配置。在当前组件访问props,使用this.props。
- props是一个组件的设置参数,能够在父控件中选择性设置。父组件对子控件的props进行赋值,而且props的值不可改变。一个子控件自身不能改变本身的 props。
- state:当一个组件 mounts的时候,state若是设置有默认值的会被使用,而且state可能时刻的被改变。一个子控件自身能够管理本身的state,可是须要注意的是,没法管理其子控件的state。因此能够认为,state是子控件自身私有的。
- 每一个组件都有属于本身的state,state和props的区别在于前者(state)只存在于组件内部,只能从当前组件调用this.setState修改state值(不能够直接修改this.state!)。
- props是一个父组件传递给子组件的数据流,能够一直的被传递到子孙组件中。然而 state表明的是子组件自身的内部状态。从语义上讲,改变组件的状态,可能会致使dom结构的改变或者从新渲染。而props是父组件传递的参数,因此能够被用于初始化渲染和改变组件自身的状态,虽然大多数时候组件的状态是又外部事件触发改变的。咱们须要知道的是,不管是state改变,仍是父组件传递的 props改变,render方法均可能会被执行。
- 通常咱们更新子组件都是经过改变state值,更新新子组件的props值从而达到更新。ajax
2.1.1 组件之间的通讯
- 父子组件数通讯
- 父与子之间通props属性进行传递
- 子与父之间,父组件定义事件,子组件触发父组件中的事件时,经过实参的形式来改变父组件中的数据来通讯
即:
- * 父组件更新组件状态 —–props—–> 子组件更新
- * 子组件更新父组件状态 —–须要父组件传递回调函数—–> 子组件调用触发
- 非父子组件之间的通讯,嵌套不深的非父子组件可使共同父组件,触发事件函数传形参的方式来实现
兄弟组件:
(1) 按照React单向数据流方式,咱们须要借助父组件进行传递,经过父组件回调函数改变兄弟组件的props。
- 其实这种实现方式与子组件更新父组件状态的方式是大同小异的。
(2) 当组件层次很深的时候,在这里,React官方给咱们提供了一种上下文方式,可让子组件直接访问祖先的数据或函数,无需从祖先组件一层层地传递数据到子组件中。
2.1.2 组件的生命周期
construtor()

2.2 vue中的组件和数据流
2.2.1 组件化应用构建
- 组件系统是 Vue 的另外一个重要概念,由于它是一种抽象,容许咱们使用小型、独立和一般可复用的组件构建大型应用。
- 在 Vue 里,一个组件本质上是一个拥有预约义选项的一个 Vue 实例
- 在一个大型应用中,有必要将整个应用程序划分为组件,以使开发可管理。
- 组件(component)是 Vue 最强大的功能之一。组件能够帮助你扩展基本的 HTML 元素,以封装可重用代码。在较高层面上,组件是 Vue 编译器附加行为后的自定义元素。在某些状况下,组件也能够是原生 HTML 元素的形式,以特定的 is 特性扩展。
- 组件中,data必须是一个函数
- 组件能够扩展 HTML 元素,封装可重用的代码。在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能。在有些状况下,组件也能够是原生 HTML 元素的形式,以 is 特性扩展。
2.2.2 响应式
- 当一个 Vue 实例被建立时,它向 Vue 的响应式系统中加入了其 data 对象中能找到的全部的属性。当这些属性的值发生改变时,视图将会产生“响应”,即匹配更新为新的值。
- 当这些数据改变时,视图会进行重渲染。值得注意的是只有当实例被建立时 data 中存在的属性是响应式的。
2.2.3 组件的生命周期
- 每一个 Vue 实例在被建立以前都要通过一系列的初始化过程。例如须要设置数据监听、编译模板、挂载实例到 DOM、在数据变化时更新 DOM 等。同时在这个过程当中也会运行一些叫作生命周期钩子的函数,给予用户机会在一些特定的场景下添加他们本身的代码。
- 好比 created 钩子能够用来在一个实例被建立以后执行代码,也有一些其它的钩子,在实例生命周期的不一样场景下调用,如 mounted、updated、destroyed。钩子的 this 指向调用它的 Vue 实例。
- 生命周期图示:

2.2.3 组件之间的通讯
- Vue默认的是单向数据流,这是Vue直接提出来讲明的,父组件默承认以向子组件传递数据,可是子组件向父组件传递数据就须要额外设置了。
- Vue 也支持双向绑定,默认为单向绑定,数据从父组件单向传给子组件。在大型应用中使用单向绑定让数据流易于理解。
- 父子组件之间的数据通讯是经过Prop和自定义事件实现的,而非父子组件可使用订阅/发布模式实现(相似于Angualr中的非父子指令之间的通讯),再复杂一点也是建议使用状态管理(vuex)。
- 在 Vue 中,父子组件之间的关系能够概述为:props 向下,events 向上。父组件经过 props 向下传递数据给子组件,子组件经过 events 发送消息给父组件。
1.父向子
- 每一个组件实例都有本身的孤立隔离做用域。也就是说,不能(也不该该)直接在子组件模板中引用父组件数据。要想在子组件模板中引用父组件数据,可使用 props 将数据向下传递到子组件。
- 每一个 prop 属性,均可以控制是否从父组件的自定义属性中接收数据。子组件须要使用 props 选项显式声明 props,以便它能够从父组件接收到指望的数据。
- 动态Props,相似于将一个普通属性绑定到一个表达式,咱们还可使用 v-bind 将 props 属性动态地绑定到父组件中的数据。不管父组件什么时候更新数据,均可以将数据向下流入到子组件中
2.子向父
- 使用自定义事件
- 每一个 Vue 实例都接入了一个事件接口(events interface),也就是说,这些 Vue 实例能够作到:
- 使用 on(eventName)监听一个事件−使用on(eventName)监听一个事件−使用emit(eventName) 触发一个事件
3. 非父子组件通讯
- 可使用一个空的 Vue 实例做为一个事件总线中心(central event bus),用emit触发事件,emit触发事件,on监听事件
2.2.4 单向数据流
单向数据流示意图:

3.状态管理
3.1 react中的状态管理:Flux
- Redux 是 React 生态环境中最流行的 Flux 实现。Redux 事实上没法感知视图层,因此它可以轻松的经过一些简单绑定和 Vue 一块儿使用。
- 建立actions
- 定义动做,事件触发须要用dispatcher来调用
- 行为,如增长操做、删除操做、更新操做,就是一堆函数。
- 建立store
- store中包含应用的状态和逻辑,用来管理应用中不一样的状态和逻辑,至关于Model层
- 建立dispatcher
- 在dispatcher中经过register来给每一个action注对应的的store中的方法
- 在view层调用action中的方法

3.2 vue中的状态管理vuex
- vuex借鉴了 Flux、Redux、和 The Elm Architecture。与其余模式不一样的是,Vuex 是专门为 Vue.js 设计的状态管理库,以利用 Vue.js 的细粒度数据响应机制来进行高效的状态更新。这使得它可以更好地和 Vue 进行整合,同时提供简洁的 API 和改善过的开发体验。
-
组件不容许直接修改属于 store 实例的 state,而应执行 action 来分发 (dispatch) 事件通知 store 去改变,咱们最终达成了 Flux 架构。这样约定的好处是,咱们可以记录全部 store 中发生的 state 改变,同时实现能作到记录变动 (mutation)、保存状态快照、历史回滚/时光旅行的先进的调试工具。
-
每个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态
-
Vuex 和单纯的全局对象有如下两点不一样:
-
Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地获得高效更新。
-
你不能直接改变 store 中的状态。改变 store 中的状态的惟一途径就是显式地提交 (commit) mutation。这样使得咱们能够方便地跟踪每个状态的变化,从而让咱们可以实现一些工具帮助咱们更好地了解咱们的应用。
-
State
- Vuex 使用单一状态树——是的,用一个对象就包含了所有的应用层级状态。至此它便做为一个“惟一数据源 (SSOT)”而存在。这也意味着,每一个应用将仅仅包含一个 store 实例。单一状态树让咱们可以直接地定位任一特定的状态片断,在调试的过程当中也能轻易地取得整个当前应用状态的快照。这也意味着,每一个应用将仅仅包含一个 store 实例。
- Getters
-
从state中获取状态值,有时候咱们须要从 store 中的 state 中派生出一些状态,例如对列表进行过滤并计数。
- Mutation
- 更改 Vuex 的 store 中的状态的惟一方法是提交 mutation。Vuex 中的 mutation 很是相似于事件:每一个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是咱们实际进行状态更改的地方,而且它会接受 state 做为第一个参数。
- 你不能直接调用一个 mutation handler。这个选项更像是事件注册:“当触发一个类型为 increment 的 mutation 时,调用此函数。”要唤醒一个 mutation handler,你须要以相应的 type 调用 store.commit 方法
-
Action
-
Module
- 因为使用单一状态树,应用的全部状态会集中到一个比较大的对象。当应用变得很是复杂时,store 对象就有可能变得至关臃肿。
- Vuex 容许咱们将 store 分割成模块(module)。每一个模块拥有本身的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行一样方式的分割

4.路由
4.1 react中的路由
- 在路由库的问题上,React 选择把问题交给社区维护,所以建立了一个更分散的生态系统。但相对的,React 的生态系统相比 Vue 更加繁荣。
- react中,须要引入react-router库,
使用时,路由器Router就是React的一个组件。
- Router组件自己只是一个容器,真正的路由要经过Route组件定义。
- Route组件定义了URL路径与组件的对应关系。你能够同时使用多个Route组件。
<Router history={hashHistory}> <Route path="/" component={App}/> <Route path="/repos" component={Repos}/> <Route path="/about" component={About}/> </Router>
4.2 vue中的路由
<div id="app"> <h1>Hello App!</h1> <p>
5. 渲染性能对比
- 在操做界面时,要尽可能减小对DOM的操做,Vue 和 React 都使用虚拟DOM来实现,而且二者工做同样好。
- 尽可能减小除DOM操做之外的其余操做。(vue和react的不一样)
5.1 react视图渲染
-
React 的渲染创建在 Virtual DOM 上——一种在内存中描述 DOM 树状态的数据结构。当状态发生变化时,React 从新渲染 Virtual DOM,比较计算以后给真实 DOM 打补丁。
-
Virtual DOM 提供了函数式的方法描述视图,它不使用数据观察机制,每次更新都会从新渲染整个应用,所以从定义上保证了视图与数据的同步。它也开辟了 JavaScript 同构应用的可能性。
-
在超大量数据的首屏渲染速度上,React 有必定优点,由于 Vue 的渲染机制启动时候要作的工做比较多,并且 React 支持服务端渲染。
-
元素是构成 React 应用的最小单位。元素用来描述你在屏幕上看到的内容,与浏览器的 DOM 元素不一样,React 当中的元素事实上是普通的对象,React DOM 能够确保 浏览器 DOM 的数据内容与 React 元素保持一致。
- 咱们用React 开发应用时通常只会定义一个根节点。但若是你是在一个已有的项目当中引入 React 的话,你可能会须要在不一样的部分单独定义 React 根节点。咱们将 元素传入一个名为 ReactDOM.render() 的方法来将其渲染到页面上,页面上就会显示该元素。
组件渲染
- 当React遇到的元素是用户自定义的组件,它会将JSX属性做为单个对象传递给该组件,这个对象称之为“props”。
5.2 vue视图渲染
6. 数据更新
6.1 react数据更新
- React 元素都是immutable 不可变的。当元素被建立以后,你是没法改变其内容或属性的。一个元素就好像是动画里的一帧,它表明应用界面在某一时间点的样子。
- 根据咱们现阶段了解的有关 React 知识,更新界面的惟一办法是建立一个新的元素,而后将它传入 ReactDOM.render() 方法
6.2 vue数据更新
7. 开发模式及规模
7.1 react
7.1.1 开发模式
7.1.2 规模
- Vue 提供了Vue-cli 脚手架,能让你很是容易地构建项目,包含了 Webpack,Browserify,甚至 no build system。
7.2 vue
7.2.1 开发模式
- Vue是MVVM模式的一种方式实现
- 虽然没有彻底遵循 MVVM 模型,Vue 的设计无疑受到了它的启发。所以在文档中常常会使用 vm (ViewModel 的简称) 这个变量名表示 Vue 实例。
7.2.2 脚手架
- React 提供了create-react-app,可是如今还存在一些局限性:
- 它不容许在项目生成时进行任何配置,而 Vue 支持 Yeoman-like 定制。
- 它只提供一个构建单页面应用的单一模板,而 Vue 提供了各类用途的模板。
- 它不能用用户自建的模板构建项目,而自建模板对企业环境下预先创建协议是特别有用的。
8. HTML&&CSS
- 在 React 中,一切都是 JavaScript。不只仅是 HTML 能够用 JSX 来表达,如今的潮流也愈来愈多地将 CSS 也归入到 JavaScript 中来处理。这类方案有其优势,但也存在一些不是每一个开发者都能接受的取舍。
- Vue 的总体思想是拥抱经典的 Web 技术,并在其上进行扩展。
8.1 react
8.1.1 JSX
8.1.2 组件做用域内的CSS
- 除非你把组件分布在多个文件上 (例如 CSS Modules),CSS 做用域在 React 中是经过 CSS-in-JS 的方案实现的 (好比 styled-components、glamorous 和 emotion)。这引入了一个新的面向组件的样式范例,它和普通的 CSS 撰写过程是有区别的。另外,虽然在构建时将 CSS 提取到一个单独的样式表是支持的,但 bundle 里一般仍是须要一个运行时程序来让这些样式生效。当你可以利用 JavaScript 灵活处理样式的同时,也须要权衡 bundle 的尺寸和运行时的开销。
8.2 vue
8.2.1 Templates模板语法
- 事实上 Vue 也提供了渲染函数,甚至支持 JSX。然而,咱们默认推荐的仍是模板。任何合乎规范的 HTML 都是合法的 Vue 模板,这也带来了一些特有的优点:
- 对于不少习惯了 HTML 的开发者来讲,模板比起 JSX 读写起来更天然。这里固然有主观偏好的成分,但若是这种区别会致使开发效率的提高,那么它就有客观的价值存在。
- 基于 HTML 的模板使得将已有的应用逐步迁移到 Vue 更为容易。
- 这也使得设计师和新人开发者更容易理解和参与到项目中。
- 你甚至可使用其余模板预处理器,好比 Pug 来书写 Vue 的模板。
- Vue.js 使用了基于 HTML 的模板语法,容许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。全部 Vue.js 的模板都是合法的 HTML ,因此能被遵循规范的浏览器和 HTML 解析器解析。
- 在底层的实现上,Vue 将模板编译成虚拟 DOM 渲染函数。结合响应系统,在应用状态改变时,Vue 可以智能地计算出从新渲染组件的最小代价并应用到 DOM 操做上。
8.2.2 单文件组件CSS
- Vue 设置样式的默认方法是单文件组件里相似 style 的标签。
单文件组件让你能够在同一个文件里彻底控制 CSS,将其做为组件代码的一部分。
- Vue 的单文件组件里的样式设置是很是灵活的。经过 vue-loader,你可使用任意预处理器、后处理器,甚至深度集成 CSS Modules——所有都在
8.3 小结
- 更抽象一点来看,咱们能够把组件区分为两类:一类是偏视图表现的 (presentational),一类则是偏逻辑的 (logical)。咱们推荐在前者中使用模板,在后者中使用 JSX 或渲染函数。这两类组件的比例会根据应用类型的不一样有所变化,但总体来讲咱们发现表现类的组件远远多于逻辑类组件。
9. 使用场景
9.1 选择react
9.1.1 期待构建一个大型应用程序——选择React
- 同时用Vue和React实现的简单应用程序,可能会让一个开发者潜意识中更加倾向于Vue。这是由于基于模板的应用程序第一眼看上去更加好理解,并且能很快跑起来。可是这些好处引入的技术债会阻碍应用扩展到更大的规模。模板容易出现很难注意到的运行时错误,同时也很难去测试,重构和分解。
相比之下,Javascript模板能够组织成具备很好的分解性和干(DRY)代码的组件,干代码的可重用性和可测试性更好。Vue也有组件系统和渲染函数,可是React的渲染系统可配置性更强,还有诸如浅(shallow)渲染的特性,和React的测试工具结合起来使用,使代码的可测试性和可维护性更好。
与此同时,React的immutable应用状态可能写起来不够简洁,但它在大型应用中意义非凡,由于透明度和可测试性在大型项目中变得相当重要。
9.1.2 期待同时适用于Web端和原生APP的框架——选择React
- React Native是一个使用Javascript构建移动端原生应用程序(iOS,Android)的库。 它与React.js相同,只是不使用Web组件,而是使用原生组件。 若是你学过React.js,很快就能上手React Native,反之亦然。
它的意义在于,开发者只须要一套知识和工具就能开发Web应用和移动端原生应用。若是你想同时作Web端开发和移动端开发,React为你准备了一份大礼。
阿里的Weex也是一个跨平台UI项目,目前它以Vue为灵感,使用了许多相同的语法,同时计划在将来彻底集成Vue,然而集成的时间和细节还不清楚。由于Vue将HTML模板做为它设计的核心部分,而且现有特性不支持自定义渲染,所以很难看出目前的Vue.js的跨平台能力能像React和React Native同样强大。
9.1.3 期待最大的生态系统——选择React
- 毫无疑问,React是目前最受欢迎的前端框架。它在NPM上每月的下载量超过了250万次,相比之下,Vue是22.5万次。人气不只仅是一个肤浅的数字,这意味着更多的文章,教程和更多Stack Overflow的解答,还意味有着更多的工具和插件能够在项目中使用,让开发者再也不孤立无援。
这两个框架都是开源的,可是React诞生于Facebook,有Facebook背书,它的开发者和Facebook都承诺会持续维护React。相比之下,Vue是独立开发者尤雨溪的做品。尤雨溪目前在全职维护Vue,也有一些公司资助Vue,可是规模和Facebook和Google没得比。不过请对Vue的团队放心,它的小规模和独立性并无成为劣势,Vue有着固定的发布周期,甚至更使人称道的是,Github上Vue只有54个open issue,3456个closed issue,做为对比,React有多达530个open issue,3447个closed issue。
9.2 选择vue
9.2.1 期待模板搭建应用——选择 Vue
- Vue应用的默认选项是把markup放在HTML文件中。数据绑定表达式采用的是和Angular类似的mustache语法,而指令(特殊的HTML属性)用来向模板添加功能。
相比之下,React应用不使用模板,它要求开发者借助JSX在JavaScript中建立DOM。
- 对于来自标准Web开发方式的新开发者,模板更容易理解。可是一些资深开发者也喜欢模板,由于模板能够更好的把布局和功能分割开来,还可使用Pug之类的模板引擎。
可是使用模板的代价是不得不学习全部的HTML扩展语法,而渲染函数只须要会标准的HTML和JavaScript。并且比起模板,渲染函数更加容易调试和测试。固然你不该该由于这方面的缘由错过Vue,由于在Vue2.0中提供了使用模板或者渲染函数的选项。
9.2.2 期待简单和“能用就行”的东西——选择 Vue
- 一个简单的Vue项目能够不须要转译直接运行在浏览器中,因此使用Vue能够像使用jQuery同样简单。固然这对于React来讲在技术上也是可行的,可是典型的React代码是重度依赖于JSX和诸如class之类的ES6特性的。
Vue的简单在程序设计的时候体现更深,让咱们来比较一下两个框架是怎样处理应用数据的(也就是state)。
- React中是经过比较当前state和前一个state来决定什么时候在DOM中进行重渲染以及渲染的内容,所以须要不可变(immutable)的state。
Vue中的数据是可变(mutated)的,因此一样的操做看起来更加简洁。
让咱们来看看Vue中是如何进行状态管理的。当向state添加一个新对象的时候,Vue将遍历其中的全部属性而且转换为getter,setter方法,如今Vue的响应系统开始保持对state的跟踪了,当state中的内容发生变化的时候就会自动从新渲染DOM。使人称道的是,Vue中改变state的状态的操做不只更加简洁,并且它的从新渲染系统也比React 的更快更有效率。
- Vue的响应系统还有有些坑的,例如:它不能检测属性的添加和删除和某些数组更改。这时候就要用到Vue API中的相似于React的set方法来解决。
9.2.3 期待应用尽量的小和快——选择Vue
- 当应用程序的状态改变时,React和Vue都将构建一个虚拟DOM并同步到真实DOM中。 二者都有各自的方法优化这个过程。
Vue核心开发者提供了一个benchmark测试,能够看出Vue的渲染系统比React的更快。测试方法是10000个项目的列表渲染100次,结果以下图。从实用的观点来看,这种benchmark只和边缘状况有关,大部分应用程序中不会常常进行这种操做,因此这不该该被视为一个重要的比较点。可是,页面大小是与全部项目有关的,这方面Vue再次领先,它目前的版本压缩后只有25.6KB。React要实现一样的功能,你须要React DOM(37.4KB)和React with Addon库(11.4KB),共计44.8KB,几乎是Vue的两倍大。双倍的体积并不能带来双倍的功能。
10. 服务器端渲染(SSR)
-
客户端渲染路线:1. 请求一个html -> 2. 服务端返回一个html -> 3. 浏览器下载html里面的js/css文件 -> 4. 等待js文件下载完成 -> 5. 等待js加载并初始化完成 -> 6. js代码终于能够运行,由js代码向后端请求数据( ajax/fetch ) -> 7. 等待后端数据返回 -> 8. react-dom( 客户端 )从无到完整地,把数据渲染为响应页面
-
服务端渲染路线:1. 请求一个html -> 2. 服务端请求数据( 内网请求快 ) -> 3. 服务器初始渲染(服务端性能好,较快) -> 4. 服务端返回已经有正确内容的页面 -> 5. 客户端请求js/css文件 -> 6. 等待js文件下载完成 -> 7. 等待js加载并初始化完成 -> 8. react-dom( 客户端 )把剩下一部分渲染完成( 内容小,渲染快 )
10.1 react
-
React的虚拟DOM是其可被用于服务端渲染的关键。首先每一个ReactComponent 在虚拟DOM中完成渲染,而后React经过虚拟DOM来更新浏览器DOM中产生变化的那一部分,虚拟DOM做为内存中的DOM表现,为React在Node.js这类非浏览器环境下的吮吸给你提供了可能,React能够从虚拟DoM中生成一个字符串。而不是跟新真正的DOM,这使得咱们能够在客户端和服务端使用同一个React Component。
-
React 提供了两个可用于服务端渲染组件的函数:React.renderToString 和React.render-ToStaticMarkup。 在设计用于服务端渲染的ReactComponent时须要有预见性,考虑如下方面。
- 选取最优的渲染函数。
- 如何支持组件的异步状态。
- 如何将应用的初始化状态传递到客户端。
- 哪些生命周期函数能够用于服务端的渲染。
- 如何为应用提供同构路由支持。
- 单例、实例以及上下文的用法。
10.2 vue
1. 什么是服务器端渲染(SSR)?
2. 服务器端渲染优点
- 更好的 SEO,因为搜索引擎爬虫抓取工具能够直接查看彻底渲染的页面。
- 更快的内容到达时间(time-to-content),特别是对于缓慢的网络状况或运行缓慢的设备。无需等待全部的 JavaScript 都完成下载并执行,才显示服务器渲染的标记,因此你的用户将会更快速地看到完整渲染的页面。一般能够产生更好的用户体验,而且对于那些「内容到达时间(time-to-content)与转化率直接相关」的应用程序而言,服务器端渲染(SSR)相当重要。
11. 附: react理念
1. 把UI图划分出组件层级
2. 用React建立一个静态版本
- 传入数据模型,渲染 UI 但没有任何交互。最好把这些过程解耦,由于建立一个静态版本更多须要的是码代码,不太须要逻辑思考,而添加交互则更多须要的是逻辑思考,不是码代码。
- 在建立静态版本的时候不要使用 state。
- 你能够自顶向下或者自底向上构建应用。也就是,你能够从层级最高的组件开始构建(即 FilterableProductTable开始)或层级最低的组件开始构建(ProductRow)。在较为简单的例子中,一般自顶向下更容易,而在较大的项目中,自底向上会更容易而且在你构建的时候有利于编写测试。
- React 的单向数据流(也叫做单向绑定)保证了一切是模块化而且是快速的。
3. 定义 UI 状态的最小(但完整)表示
4. 肯定你的State应该位于哪里
-
对你应用的每个 state:
- 肯定每个须要这个 state 来渲染的组件。
- 找到一个公共全部者组件(一个在层级上高于全部其余须要这个 state 的组件的组件)
- 这个公共全部者组件或另外一个层级更高的组件应该拥有这个 state。
- 若是你没有找到能够拥有这个 state 的组件,建立一个仅用来保存状态的组件并把它加入比这个公共全部者组件层级更高的地方。
5. 添加反向数据流
小结
总结一下,咱们发现,
- Vue的优点包括:
- 模板和渲染函数的弹性选择
- 简单的语法及项目建立
- 更快的渲染速度和更小的体积
- React的优点包括:
- 更适用于大型应用和更好的可测试性
- 同时适用于Web端和原生App
- 更大的生态圈带来的更多支持和工具
- 而实际上,React和Vue都是很是优秀的框架,它们之间的类似之处多过不一样之处,而且它们大部分最棒的功能是相通的:
- 利用虚拟DOM实现快速渲染
- 轻量级
- 响应式和组件化
- 服务器端渲染
- 易于集成路由工具,打包工具以及状态管理工具
- 优秀的支持和社区
文章参考来源: