放两张图镇压小妖怪css
本文先讲共同之处,html
再分析区别vue
大纲在此:node
共同点:react
a、都使用虚拟domwebpack
b、提供了响应式和组件化的视图组件web
c、注意力集中保持在核心库,而将其余功能如路由和全局状态管理交给相关的库。ajax
区别:算法
a、优化vue-router
b、HTML&CSS
c、构建工具
d、数据绑定
e、状态管理
f、路由
g、渲染性能
h、数据更新
i、开发模式及规模
j、使用场景
k、服务器端渲染(SSR)
l、扩展(高阶组件和mixin)
一、都使用虚拟DOM
vue:Vue在2.0版本引入了vdom。其vdom是基于 snabbdom 库所作的修改。snabbdom是一个开源的vdom库。snabbdom的主要做用就是将传入的JS模拟的DOM结构转换成虚拟的DOM节点。先经过其中的 h函数 将JS模拟的DOM结构转换成虚拟DOM以后,再经过其中的 patch函数 将虚拟DOM转换成真实的DOM渲染到页面中。为了保证页面的最小化渲染,snabbdom引入了 Diff算法 ,经过Diff算法找出先后两个虚拟DOM之间的差别,只更新改变了的DOM节点,而不从新渲染为改变的DOM节点。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title></head><body> <p id="container"></p> <button id="btn-change">change</button> <!-- 引入snabbdom库,先没必要纠结为何这样引入,以及每一个文件的做用。 --> <script src="https://cdn.bootcss.com/snabbdom/0.7.1/snabbdom.js"></script> <script src="https://cdn.bootcss.com/snabbdom/0.7.1/snabbdom-class.js"></script> <script src="https://cdn.bootcss.com/snabbdom/0.7.1/snabbdom-props.js"></script> <script src="https://cdn.bootcss.com/snabbdom/0.7.1/snabbdom-style.js"></script> <script src="https://cdn.bootcss.com/snabbdom/0.7.1/snabbdom-eventlisteners.js"></script> <script src="https://cdn.bootcss.com/snabbdom/0.7.1/h.js"></script> <script> //定义patch函数 var patch = snabbdom.init([ snabbdom_class, snabbdom_props, snabbdom_style, snabbdom_eventlisteners ]) //定义h函数 var h = snabbdom.h; //生成一个vnode var vnode = h('ul#list',{},[ h('li.item',{},['Item 1']), h('li.item',{},['Item 2']), ]) //console.log(vnode); //获取container var container = document.getElementById('container'); patch(container,vnode);//初次渲染 var btn = document.getElementById('btn-change'); btn.onclick = function() { var newVnode = h('ul#list',{},[ h('li.item',{},['Item 1']), h('li.item',{},['Item B']), h('li.item',{},['Item 3']), ]) patch(vnode,newVnode);//再次渲染 vnode = newVnode;//将修改后的newVnode赋值给vnode } </script> </body> </html>
vue中的模板解析和渲染的核心就是:经过相似snabbdom的h()和patch()的函数,先将模板解析成vnode,若是是初次渲染,则经过patch(container,vnode)将vnode渲染至页面,若是是二次渲染,则经过patch(vnode,newVnode),先经过Diff算法比较原vnode和newVnode的差别,以最小的代价从新渲染页面。
react:react定义的一种相似于XML的JS扩展语法:XML+JS。
做用:用来建立react虚拟DOM(元素)对象。
//使用虚拟DOM import React from 'react' import ReactDOM from 'react-dom' import App from './App' import { BrowserRouter } from 'react-router-dom' import { Provider } from 'react-redux' import 'styles/reset.css' import 'styles/animate.css' import store from './store' ReactDOM.render( <Provider store={store}> <BrowserRouter> <App /> </BrowserRouter> </Provider>, document.getElementById('root') )
二、都提供了响应式和组件化的视图组件
三、都把注意力集中保持在核心库,而将其余功能如路由和全局状态管理交给相关的库。(vue-router、vuex、react-router、redux等等)
四、优化
react:
在 React 应用中,当某个组件的状态发生变化时,它会以该组件为根,从新渲染整个组件子树。
如要避免没必要要的子组件的重渲染,
你须要在全部可能的地方使用 PureComponent
,
或是手动实现 shouldComponentUpdate
方法。
react优化方法:
a、shouldComponentUpdate
b、immutable
能够看看:http://www.javashuo.com/article/p-umzowdst-dr.html
c、react-immutable-render-mixin,实现装饰器简化不少写法
d、无状态组件
e、高阶组件
vue:
在 Vue 应用中,组件的依赖是在渲染过程当中自动追踪的,
因此系统能精确知晓哪一个组件确实须要被重渲染。
你能够理解为每个组件都已经自动得到了 shouldComponentUpdate
,而且没有上述的子树问题限制。
Vue 的这个特色使得开发者再也不须要考虑此类优化,从而可以更好地专一于应用自己。
五、HTML&CSS
react:
在 React 中,一切都是 JavaScript。
在 React 中,全部的组件的渲染功能都依靠 JSX。
JSX 是使用 XML 语法编写 JavaScript 的一种语法糖。
import React, { Component } from 'react' import { SearchContainer, SearchContent } from './styledComponent.js' import search from 'images/search.png' class Search extends Component { render () { return ( <SearchContainer> <SearchContent { ...this.props }> <img src={search} alt=""/> <span>想吃什么搜这里,川菜</span> </SearchContent> </SearchContainer> ) } } export default Search
vue:
vue是把html,css,js组合到一块儿,用各自的处理方式
Vue 设置样式的默认方法是单文件组件里相似 style
的标签。
<template> <div class="m-movie"> <div class="white-bg topbar-bg"> <div class="city-entry"> <router-link tag="span" to="/cities" class="city-name">北京</router-link> </div> <div class="switch-hot"> <router-link tag="div" to="/home/movies/intheater" active-class="active" class="hot-item">正在热映</router-link> <router-link tag="div" to="/home/movies/coming" active-class="active" class="hot-item">即将上映</router-link> </div> </div> <transition :name="transitionName"> <router-view class="movies-outlet"></router-view> </transition> </div> </template> <script> export default { data () { return { transitionName: '' } }, watch: { $route (to, from) { if ( to.meta > from.meta ) { this.transitionName = 'slide-left' } else { this.transitionName = 'slide-right' } } } } </script> <style lang="stylus" scoped> @import '~styles/border.styl' @import '~styles/variables.styl' .slide-right-enter-active, .slide-right-leave-active, .slide-left-enter-active, .slide-left-leave-active { transition: all 1s; } .slide-right-enter { opacity: 0; transform: translate3d(-100%, 0, 0); } .slide-right-leave-to { opacity: 0; transform: translate3d(100%, 0, 0); } .slide-left-enter { opacity: 0; transform: translate3d(100%, 0, 0); } .slide-left-leave-to { opacity: 0; transform: translate3d(-100%, 0, 0); } </style>
关于.vue文件怎么运行的能够看:
http://www.javashuo.com/article/p-cpdupjwu-en.html
六、 构建工具
react:
构建:create-react-app 快速脚手架
creat-react-app优势 无需配置:官方的配置堪称完美,几乎不用你再配置任何东西,就能够上手开发项目。 高集成性:集成了对React,JSX,ES6和Flow的支持。 自带服务:集成了开发服务器,你能够实现开发预览一体化。 热更新:保存自动更新,让你的开发更简单。 全兼容性:自动处理CSS的兼容问题,无需添加-webkit前缀。 自动发布:集成好了发布成品功能,编译后直接发布,而且包含了sourcemaps功能。
npm install -g create-react-app
create-react-app my-app(本身的项目名称)
cd my-app
npm start
vue:
构建:vue-cli脚手架
yarn global add @vue/cli (vue/cli是webpack的二次开发)
七、数据绑定
vue:vue是双向绑定, Vue.js 最核心的功能有两个,一是响应式的数据绑定系统,二是组件系统。所谓双向绑定,指的是vue实例中的data与其渲染的DOM元素的内容保持一致,不管谁被改变,另外一方会相应的更新为相同的数据。这是经过设置属性访问器实现的。
Vue 的依赖追踪是【原理上不支持双向绑定,v-model 只是经过监听 DOM 事件实现的语法糖】
vue的依赖追踪是经过 Object.defineProperty 把data对象的属性所有转为 getter/setter来实现的;当改变数据的某个属性值时,会触发set函数,获取该属性值的时候会触发get函数,经过这个特性来实现改变数据时改变视图;也就是说只有当数据改变时才会触发视图的改变,反过来在操做视图时,只能经过DOM事件来改变数据,再由此来改变视图,以此来实现双向绑定
双向绑定是在同一个组件内,将数据和视图绑定起来,和父子组件之间的通讯并没有什么关联;
组件之间的通讯采用单向数据流是为了组件间更好的解耦,在开发中可能有多个子组件依赖于父组件的某个数据,假如子组件能够修改父组件数据的话,一个子组件变化会引起全部依赖这个数据的子组件发生变化,因此vue不推荐子组件修改父组件的数据,直接修改props会抛出警告
思想是响应式的,也就是基因而数据可变的,经过对每个属性创建Watcher来监听, 当属性变化的时候,响应式的更新对应的虚拟dom
react:react是单向数据流;react中经过将state(Model层)与View层数据进行双向绑定达数据的实时更新变化,具体来讲就是在View层直接写JS代码Model层中的数据拿过来渲染,一旦像表单操做、触发事件、ajax请求等触发数据变化,则进行双同步。推崇结合immutable来实现数据不可变。 能够看看:http://www.javashuo.com/article/p-umzowdst-dr.html。react在setState以后会从新走渲染的流程,若是shouldComponentUpdate返回的是true,就继续渲染, 若是返回了false,就不会从新渲染,PureComponent就是重写了shouldComponentUpdate, 而后在里面做了props和state的浅层对比;
八、状态管理
react:redux
能够看看:http://www.javashuo.com/article/p-xiimfjzp-y.html
vue:vuex
能够看看:http://www.javashuo.com/article/p-kejnimiv-ge.html
九、路由
能够直接看这个,很详细react router @4 和 vue路由 详解(全):http://www.javashuo.com/article/p-rfhkumuv-be.html
十、渲染性能
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() 的方法来将其渲染到页面上,页面上就会显示该元素。
vue:
Vue 经过创建一个虚拟 DOM 对真实 DOM 发生的变化保持追踪。
vue渲染的过程以下:
new Vue,执行初始化
挂载$mount方法,经过自定义Render方法、template、el等生成Render函数
经过Watcher监听数据的变化
当数据发生变化时,Render函数执行生成VNode对象
经过patch方法,对比新旧VNode对象,经过DOM Diff算法,添加、修改、删除真正的DOM元素
十一、数据更新
react:
React 元素都是immutable 不可变的。当元素被建立以后,你是没法改变其内容或属性的。一个元素就好像是动画里的一帧,它表明应用界面在某一时间点的样子。
根据咱们现阶段了解的有关 React 知识,更新界面的惟一办法是建立一个新的元素,而后将它传入 ReactDOM.render() 方法
vue:
数据直接修改,响应式。
十二、开发模式及规模
react:
React自己,是严格的view层,MVC模式
vue:
1三、使用场景
react:
a、构建一个大型应用项目
同时用Vue和React实现的简单应用程序,可能会让一个开发者潜意识中更加倾向于Vue。这是由于基于模板的应用程序第一眼看上去更加好理解,并且能很快跑起来。
可是这些好处引入的技术债会阻碍应用扩展到更大的规模。
模板容易出现很难注意到的运行时错误,同时也很难去测试,重构和分解。
相比之下,Javascript模板能够组织成具备很好的分解性和干(DRY)代码的组件,干代码的可重用性和可测试性更好。
Vue也有组件系统和渲染函数,可是React的渲染系统可配置性更强,还有诸如浅(shallow)渲染的特性,和React的测试工具结合起来使用,使代码的可测试性和可维护性更好。
与此同时,React的immutable应用状态可能写起来不够简洁,但它在大型应用中意义非凡,由于透明度和可测试性在大型项目中变得相当重要。
b、同时适用于Web端和原生APP
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同样强大。
vue:
a、期待模板搭建应用
b、期待应用尽量的小和快
当应用程序的状态改变时,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的两倍大。
双倍的体积并不能带来双倍的功能。
1四、服务器端渲染(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( 客户端 )把剩下一部分渲染完成( 内容小,渲染快 )
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时须要有预见性,考虑如下方面。
选取最优的渲染函数。
如何支持组件的异步状态。
如何将应用的初始化状态传递到客户端。
哪些生命周期函数能够用于服务端的渲染。
如何为应用提供同构路由支持。
单例、实例以及上下文的用法。
vue:
Vue.js 是构建客户端应用程序的框架。默认状况下,能够在浏览器中输出 Vue 组件,进行生成 DOM 和操做 DOM。然而,也能够将同一个组件渲染为服务器端的 HTML 字符串,将它们直接发送到浏览器,最后将静态标记”混合”为客户端上彻底交互的应用程序。
服务器渲染的 Vue.js 应用程序也能够被认为是”同构”或”通用”,由于应用程序的大部分代码均可以在服务器和客户端上运行。
服务器端渲染优点
- 更好的 SEO,因为搜索引擎爬虫抓取工具能够直接查看彻底渲染的页面。
- 更快的内容到达时间(time-to-content),特别是对于缓慢的网络状况或运行缓慢的设备。无需等待全部的 JavaScript 都完成下载并执行,才显示服务器渲染的标记,因此你的用户将会更快速地看到完整渲染的页面。一般能够产生更好的用户体验,而且对于那些「内容到达时间(time-to-content)与转化率直接相关」的应用程序而言,服务器端渲染(SSR)相当重要。
1五、扩展(高阶组件和mixin)
react能够经过高阶组件(Higher Order Components--HOC)来扩展,而vue须要经过mixins来扩展
React刚开始也有mixin的写法,经过React.createClass的api,不过如今不多用了。
Vue也不是不能实现高阶组件,只是特别麻烦,由于Vue对与组件的option作了各类处理, 想实现高阶组件就要知道每个option是怎么处理的,而后正确的设置。
mixin小介绍:
vue中提供了一种混合机制--mixins,用来更高效的实现组件内容的复用。最开始我一度认为这个和组件好像没啥区别。。后来发现错了。下面咱们来看看mixins和普通状况下引入组件有什么区别?
组件在引用以后至关于在父组件内开辟了一块单独的空间,来根据父组件props过来的值进行相应的操做,单本质上二者仍是泾渭分明,相对独立。
而mixins则是在引入组件以后,则是将组件内部的内容如data等方法、method等属性与父组件相应内容进行合并。至关于在引入后,父组件的各类属性方法都被扩充了。
单纯组件引用:
父组件 + 子组件 >>> 父组件 + 子组件
mixins:
父组件 + 子组件 >>> new父组件
做用:多个组件能够共享数据和方法,在使用mixin的组件中引入后,mixin中的方法和属性也就并入到该组件中,能够直接使用。钩子函数会两个都被调用,mixin中的钩子首先执行。
下面给你们介绍vue mixin的用法,具体介绍以下所示:
//mixin.js export default { data() { return { name: 'mixin' } }, created() { console.log('mixin...', this.name); }, mounted() {}, methods: {} }
使用:
vue文件中使用 import '@/mixin'; // 引入mixin文件 export default { mixins: [mixin] }
小结
总结一下,咱们发现,
- Vue的优点包括:
- 模板和渲染函数的弹性选择
- 简单的语法及项目建立
- 更快的渲染速度和更小的体积
- React的优点包括:
- 更适用于大型应用和更好的可测试性
- 同时适用于Web端和原生App
- 更大的生态圈带来的更多支持和工具
- 而实际上,React和Vue都是很是优秀的框架,它们之间的类似之处多过不一样之处,而且它们大部分最棒的功能是相通的:
- 利用虚拟DOM实现快速渲染
- 轻量级
- 响应式和组件化
- 服务器端渲染
- 易于集成路由工具,打包工具以及状态管理工具
- 优秀的支持和社区
参考1:https://blog.csdn.net/CystalVon/article/details/78428036 参考2:https://cn.vuejs.org/v2/guide/comparison.html 参考3:https://www.cnblogs.com/suihang/p/10098860.html参考4:https://www.jb51.net/article/138757.htm