欢迎大家关注腾讯云技术社区-博客园官方主页,我们将持续在博客园为大家推荐技术精品文章哦~

纪俊,从事Web前端开发工作,2016年加入腾讯OMG广告平台产品部,喜欢研究前端技术框架。

这里要讨论的话题,不是前端框架哪家强,因为在 Vue 官网就已经有了比较全面客观的介绍,并且是中文的。

上图是二月份前端框架排名,React 位居第一,Vue 排名第三。还清晰记得,16 年十月份该 showcase 首页并未看到 Vue,如今已有 40000+ stars,那时的 React 也差不多这个成绩,可见 Vue 2.0 有多受关注,而排名第二的 Angular 当时位居第一,短短数月 React、Vue 都有比较好的成绩,而 Angular 的 stars 没有明显增长,是否可以断章取义,Angular 正在慢慢地退出这个舞台。

对于近期关注度最高的 React 和 Vue,想在这里谈谈两个框架在开发风格上的差异。Vue 升级到2.0之后新增了很多 React 原有的特性,我的理解是 Vue 在这些方面对 React 的肯定和致敬,下面将在几个细节上作对比。

Vue更容易上手

Vue 更容易上手!这是真的吗?我书读的少,作者是想支持国产吗?

Vue 的语法很自由,比如:

  • 前期不需要认识复杂的生命周期函数,可能只关心 mounted 和 Vue.nextTick(保证 this.$el 在 document 中)

  • 熟悉的前端模板

  • 父子组件间通信更灵活

  • slot,可以大尺度地扩展组件(但也不要过度使用哦)

  • v-model,mvvm 的方式处理表单更方便

  • 官网中文文档(哈哈,不得不承认)

从入门学习一个框架的角度看,少一些规则多一些自由空间,门槛会低些。

表单在 React 中的蛋疼之处

React 和 Vue 如何拿 input 的 value,先上代码

Reactjs

  1. class Demo extends React.Component{
  2. constructor(props){
  3. super(props)
  4. this.state={
  5. inputA: '',
  6. inputB: ''
  7. }
  8. }
  9. _onChangeA(e){
  10. this.setState({
  11. inputA: e.target.value
  12. })
  13. }
  14. _onChangeB(e){
  15. this.setState({
  16. inputB: e.target.value
  17. })
  18. }
  19. render() {
  20. return (
  21. <div>
  22. <input
  23. onChange={this._onChangeA.bind(this)}
  24. value={this.state.inputA}
  25. />
  26. <input
  27. onChange={this._onChangeB.bind(this)}
  28. value={this.state.inputB}
  29. />
  30. </div>
  31. );
  32. }
  33. };
  34.  
  35. ReactDOM.render(
  36. <Demo/>,
  37. document.getElementById('container')
  38. );

Vuejs

  1. <div id="demo">
  2. <input
  3. v-model="inputA"
  4. :value="inputA"/>
  5. <input
  6. v-model="inputB"
  7. :value="inputB"
  8. />
  9. <button
  10. @click="show"
  11. >
  12. show
  13. </button>
  14. </div>
  15. new Vue({
  16. el: '#demo',
  17. data: {
  18. inputA: '',
  19. inputB: ''
  20. }
  21. })

Vue 进行表单处理的方式是不是更简洁,由于 v-model 属性支持数据双向绑定,说白了就是(value 的单向绑定 + onChange 事件监听)的语法糖,但这个味道还不错吧,比起在 React 中需要绑定多个 onChange 事件确实要方便得多。

JSX vs Templates

刚接触 React,因为用惯了javascript 模板引擎,一直坚信视图与功能逻辑分离是正确的选择,突然看到 JSX 把 html 写在 js 里,内心是拒绝的!

Facebook 官方好像知道大家对 JSX 有偏见,在文档一开始就给出解释

We strongly believe that components are the right way to separate concerns rather than “templates” and “display logic.” We think that markup and the code that generates it are intimately tied together. Additionally, display logic is often very complex and using template languages to express it becomes cumbersome.

在这里结合我的理解翻译一下, React 团队坚信一个组件的正确用途是 “separate concerns”,而不是前端模板或者展示逻辑。我们认为前端模板和组件代码是紧密相连的。另外,模板语言经常让展示的逻辑变得更复杂。

刚开始没弄明白什么是 “separate concerns”,其实现在也… Facebook 可能是在强调组件应该从功能上去抽象定义,而不仅仅从视觉上区分。

组件通信

Vue 组件向上通信可通过触发事件,但在 Vue 2.0 废弃 dispatch,建议使用global event bus。而大多初学者以为 React 只能靠调用父组件的 callback,并且这种方式遇到组件层次太深的时候简直就是噩梦。其实 React 也可以通过事件通信来解决问题,只不过需要额外 coding 或调用第三方插件,而 Vue 的核心库已实现了该功能。React 拥有丰富的生态圈,很多事情是大家一起完成的。

ref or props

父组件可通过 ref 定位子组件并调用它的 api,也可通过 props 传递数据,实现父组件通知子组件,ref 和 props 这两种方式将决定组件的形态。在实际开发中,可能 Vue 先入为主,ref 也用的比较多,因为它在组件封装力度上确实有优势, api 可让组件更抽象、更关注自身的功能,不受外界影响。而后来转到 React 几乎都是用 props 通信,一开始还以为是 React 的问题,甚至还得出了这样的结论:React 组件像是 UI 组件,Vue 组件更接近对象。直到最近看了 Facebook 文档,才发现另有蹊跷。先看看之前用 Vue ,我是如何去创建一个列表(List)组件,并实现列表数据的新增和删除,以及调用方式。

没用过 ref 的同学,可以先看下文档,不过看完下面代码也能大概知道 ref 的作用。

Vuejs

  1. <div id="demo">
  2. <input
  3. v-model="inputA"
  4. :value="inputA"/>
  5. <input
  6. v-model="inputB"
  7. :value="inputB"
  8. />
  9. <button
  10. @click="show"
  11. >
  12. show
  13. </button>
  14. </div>
  15. new Vue({
  16. el: '#demo',
  17. data: {
  18. inputA: '',
  19. inputB: ''
  20. }
  21. })

再看看 React 是怎么做的

  1. class List extends React.Component{
  2. _delete(index){
  3. this.props.onDelete && this.props.onDelete(index)
  4. }
  5. render() {
  6. return (
  7. <ul>
  8. {
  9. this.props.list.map((item, index)=>{
  10. return (
  11. <li
  12. key={index}
  13. >
  14. {item}
  15. <i onClick={this._delete.bind(this, index)}>
  16. delete
  17. </i>
  18. </li>
  19. )
  20. })
  21. }
  22. </ul>
  23. );
  24. }
  25. };
  26.  
  27. class Page extends React.Component{
  28. constructor(props){
  29. super(props)
  30. this.state={
  31. input: '',
  32. list: []
  33. }
  34. }
  35. _bindChange(e){
  36. this.setState({
  37. input: e.target.value
  38. })
  39. }
  40. _add(){
  41. this.state.list.push(this.state.input)
  42. this.forceUpdate()
  43. }
  44. _delete(index){
  45. this.state.list.splice(index, )
  46. this.forceUpdate()
  47. }
  48. render() {
  49. return (
  50. <div>
  51. <input
  52. onChange={this._bindChange.bind(this)}
  53. value={this.state.input}
  54. />
  55. <button
  56. onClick={this._add.bind(this)}
  57. >
  58. add
  59. </button>
  60. <List
  61. list={this.state.list}
  62. onDelete={this._delete.bind(this)}
  63. />
  64. </div>
  65. );
  66. }
  67. };
  68.  
  69. ReactDOM.render(
  70. <Page/>,
  71. document.getElementById('container')
  72. );

通过上面两段代码可以看出,在调用 List 组件的时候,React 比 Vue 复杂的多,不仅仅是多了 onChange,还有新增和删除的逻辑,都必须在父组件中实现,这样会导致项目中多处调用 List 组件,都必须实现这套相似的逻辑,而这套逻辑在 Vue 中已封装在组件里,这也是为什么利用 ref 在封装力度上有优势,所以给我的感觉,React 比较关注组件的展示,而 Vue 比较关注功能。

细心的同学可能发现了,React也有ref 属性,它也可以让父组件调用子组件的 api,但实际项目中却很少看到,为什么大家都这么同步一致呢?我查了一下文档,原来 Facebook 不推荐过度使用 ref

Your first inclination may be to use refs to “make things happen” in your app. If this is the case, take a moment and think more critically about where state should be owned in the component hierarchy. Often, it becomes clear that the proper place to “own” that state is at a higher level in the hierarchy. See the Lifting State Up guide for examples of this.

官方还有个栗子,这里我也举个比较常见的

基于上面的栗子,比如现在列表数据多啦!需要在列表顶部显示有多少条数据!我们可以定义一个显示条数的组件 Counts。

Vuejs

  1. var bus = new Vue()
  2. var Counts = Vue.extend({
  3. data: function(){
  4. return{
  5. count:
  6. }
  7. },
  8. template: '<span>{{count}}</span>',
  9. mounted: function(){
  10. var self = this
  11. bus.$on('plus', function(){
  12. self.count++
  13. })
  14. bus.$on('minus', function(){
  15. self.count--
  16. })
  17. }
  18. })
  19. Vue.component('Count', Count)
  20. Reactjs
  21.  
  22. let Counts = (props)=>{
  23. return (
  24. <span>
  25. {props.count}
  26. </span>
  27. );
  28. }

如按照 Vue 的实现方法(好吧!这里好像要黑 Vue,其实是我一开始的误解),Counts 组件需监听两个事件(plus & minus),在事件回调中去更新条数,当 List 进行add() 或 delete() 需触发plus / minus,且不说 Counts 组件复杂,这事件流也很难追溯,代码放久看着吃力!但 React 把共享数据抽离了,父组件把this.state.list.length通过 props 传入 Counts,这种方式逻辑更清晰,扩展能力更强。虽然像 React 这种,在不需要组件共享数据时,调用起来很繁琐,调用 List 时add / delete 逻辑都要写一遍,但业务的发展很难说,很多意想不到的情况都会发生,比如上面的栗子,后期指不定还要加一个分页组件呢,所以我悬崖勒马,以后不管在 Vue 还是 React,尽量少用 ref 调用子组件。当组件之间有共享数据时,该数据与操作该数据的逻辑,应该放在最接近它们的父组件,这样组件的逻辑会更合理,更清晰!

最后,这两个框架的路线有差异,Vue 偏向大而全,把很多特性都封装进核心库,React 则不同,React 核心库只是 React 生态圈很小一部分,只负责 view 这个层面,其它事情都是由大家一起完成,所以 React 会有这么多插件。Reactjs 和 Vuejs 都是伟大的框架!

欢迎加入QQ群:374933367,与腾云阁原创作者们一起交流,更有机会参与技术大咖的在线分享!

相关阅读

Vue.js前后端同构方案之准备篇——代码优化
Vue.js 实战总结
React 同构思想


此文已由作者授权腾讯云技术社区发布,转载请注明文章出处
原文链接:https://www.qcloud.com/community/article/359850
获取更多腾讯海量技术实践干货,欢迎大家前往腾讯云技术社区

Reactjs vs. Vuejs的更多相关文章

  1. vueJS+ES6开发移动端APP实战项目笔记

    一.什么是MVVM框架 MV*包括MVC.MVP.MVVM MVVM框架由Model.View.ViewModel构成. Model指的是数据,在前端对应的是JavaScript对象. View指的是 ...

  2. 微信小程序初探

    做为码农相信大家最近肯定都会听到微信小程序,虽然现阶段还没有正式开放注册,但大家可以还是可以开发测试. 到微信的WIKI(http://mp.weixin.qq.com/wiki?t=resource ...

  3. Wijmo 2016 V3发布

    互操作性增强 Wijmo继续扩展互操作性包括Angular 2.ReactJS和VueJS. 模块支持 Wijmo最初设计为单个模块. 一切都存储在Wijmo命名空间.Wijmo现在包含很多不同的模块 ...

  4. 实现checkbox组件化(Component)

    之前我写了一篇自定义checkbox的文章,通过css3实现自定义的checkbox,并没有使用当今流行的Reactjs, 或者Vuejs之类的进行组件化.但是很显然,这样封装的checkbox组件复 ...

  5. Vue和React对比

    Vue和React对比 Vue也已经升级到2.0版本了,到现在为止(2016/11/19)比较流行的MVVM框架有AngularJS(也有人认为其为MVC).ReactJS和VueJS,这三个框架中, ...

  6. Nodejs的运行原理-科普篇

    前言 Nodejs目前处境稍显尴尬,很多语言都已经拥有异步非阻塞的能力.阿里的思路是比较合适的,但是必须要注意,绝对不能让node做太多的业务逻辑,他只适合接收生成好的数据,然后或渲染后,或直接发送到 ...

  7. web开发-前后端分离原理

    前言 前后端分离已成为互联网项目开发的业界标准使用方式,通过Nginx+Tomcat的方式(也可以中间加一个Node.js)有效的进行解耦,并且前后端分离会为以后的大型分布式架构.弹性计算架构.微服务 ...

  8. Wijmo 2017路线图

    2016年是Wijmo团队发展和增长的另一个富有成效的一年.回顾我们2016年的路线图,您可以看到我们交付了我们承诺的一切.让我们回顾一下2016年的亮点: 我们第一个全面支持Angular 2 互操 ...

  9. (转)2018几大主流的UI/JS框架——前端框架 [Vue.js(目前市场上的主流)]

    https://blog.csdn.net/hu_belif/article/details/81258961 2016年开始应该是互联网飞速发展的几年,同时也是Web前端开发非常火爆的一年,Web ...

随机推荐

  1. C# 6 与 .NET Core 1.0 高级编程 - 41 ASP.NET MVC(下)

    译文,个人原创,转载请注明出处(C# 6 与 .NET Core 1.0 高级编程 - 41 ASP.NET MVC(下)),不对的地方欢迎指出与交流. 章节出自<Professional C# ...

  2. javascript中构造StringBuffer实例

    function StringBuffer(){      this.strings = new Array;  }    StringBuffer.prototype.append=function ...

  3. iOS开发之判断横竖屏切换

    /** *  当屏幕即将旋转的时候调用 * *  @param toInterfaceOrientation 旋转完毕后的最终方向 *  @param duration  旋转动画所花费的时间 */ ...

  4. CentOs6系统安装mailx发邮件

    1. yum -y mail* sendmail* postfix* service sendmail start 2. cp /etc/mail.rc /etc/mail.rc.bak cat &g ...

  5. python3编码问题终结者--还搞不懂你来找我

    python unicode bytes str 编码 首先需要说明一下,该篇文章是以python3为基础的,python2是否适合没有验证过.由于python编码问题确实比较多,文章篇幅可能较长,请 ...

  6. PPAPI插件开发指南

    转载请注明出处:http://www.cnblogs.com/fangkm/p/4401075.html 前言 插件一直是浏览器的重要组成部分,丰富浏览器的运行能力,实现一些HTML+JS实现不了本地 ...

  7. Akari谜题(关灯问题)的开灯解法

    提高解时预处理的速度 本方法的结果是得到满足所有黑色有数字方块的一个带有未照亮的块的可能解集. 解集大小为 4~(3号块数量+1号块数量)+6~(2号块数量)-灯互相照射到的解的集合.集合中的灯为黄色 ...

  8. 持续集成:TestNG中case之间的关系

    持续集成:TestNG中case之间的关系   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家咨询qq: ...

  9. 老李分享:接电话扩展之uiautomator 2

    主要的类就是上面的PhoneReceiver广播接收者.来电的时候,我们记录下电话号码,等该来电挂断以后,立即回拨给对方.配置文件如下: <?xml version="1.0" ...

  10. 前端开发框架简介:angular和react

    作者:vienwu react是facebook推出一个用来构建用户界面的js库.官方介绍的三大特性如下: just the ui 把react只当作一个ui组件就好,等同于传统mvc中的view. ...