jQuery对比React.js的思考

前面的文章或多或少提到了React.js。React.js能带来什么好处?让我们来分析一下常用的jQuery和React之间的不同。

问题描述:

有一个项目列表,每个条目默认带有隐藏着的详细信息。当用户点击某一条就展开并显示该条目的详细信息。其他的条目则变灰。当我们再次点击同一条项目时,就收起,其他的条目恢复到初始状态:收起和黑色字体。我们也可以展开其他条目,来收起之前展开的条目。

2种解决方案:

jQuery (JSBin)

我们的数据和状态包含在了DOM中,并没有结构化。数据,状态,表现之间显得比较冗杂。
我们使用jQuery选择器(像is(‘hidden’).find(‘.details’))。然后我们用hide(),show(),addClass()removeClass()方法直接操作DOM来改变状态。
写完这些代码后过段时间再回来看,需要从头到尾重新阅读一遍代码才能理解。由于功能有限,我可以不用破坏原有代码来重构这个功能。但是当我们增加复杂的特征后恐怕没那么容易了。
React (JSBin)

我的第一反应是“哇,这么多代码,用这库不够好吧”,真是这样吗?我们来分析一下:

  • 数据漂亮地独立了出来,存到PRODUCTS这个数组中
  • 所有状态用expandedProductId这个变量
  • 所有的渲染逻辑写在了render方法中
  • 我们能从头到尾阅读代码
  • 快速浏览代码后容易理解代码所做的事情

结论

这个例子比较简单,但能够显示出两个库是如何帮助你把你所关注的部分分离出来,React无疑是更好的选择,它让我们把数据抽离出来,注意力集中在这些数据的处理上,至于页面的渲染,就交给React吧。
原文:jQuery versus React.js thinking

谈谈MVC模式和未来

就拿百度来举例吧,首先不去管它采用了什么技术,可以从他的改变来猜测。
以前我们是在首页的搜索框先输入关键词,这时除了弹出个搜索建议外没任何改变,用户敲了回车键或者点搜索按钮就跳转到结果列表页了,若更换关键词,则需要再点搜索按钮,页面刷新给出结果。
现在的百度首页已经做了大幅优化了,来看看整个搜索流程:当我们输入第一个字符时,貌似自动跳到结果页面了,当输入的字符能成关键词了,便列出结果。当我们改变搜索框的关键词,页面又立马更新了结果列表。可以推测技术上采用了某种单页面应用架构,响应速度很快,这更像是一个本地app,大大提高了用户体验。

用MVC模式来分析一下整个过程:

  • 用户和View发生交互
  • View传送指令到Controller
  • Controller完成业务逻辑后,要求Model改变状态
  • Model将新的数据发送到View,用户得到反馈

现在MVC的框架有很多,有些采用了衍生的MVP、MVVM等架构,想搞清楚这几者的区别可参考阮一峰的一篇文章MVC,MVP 和 MVVM 的图示
对于复杂的软件,MVC带来的好处是显而易见的,不仅有合理的架构,给以后的维护也带来很大的方便。
但前端技术总是发展的特别快(可以看看这篇文章The Future of JavaScript MVC Frameworks),MVC中使用模板进行渲染,通过双向绑定使得应用复杂度增加了,而Facebook的React.js采用组件化的形式,每当有操作进行数据更新,就对整个页面进行渲染,避免了复杂的状态维护,可以参考JavaScript与有限状态机这篇文章。而我前面写的一篇文章What happend about Angular2.0表示Angular2.0也在朝着这个方向走。
javascript-mvc

React 框架本身作为MVC当中的V存在, 提供两个功能:

  • 渲染和维护 DOM
  • 监听 DOM 的事件

其他的好处是:

  • React Component 设计得非常适合模块化
  • Component和DOM得益于Virtual DOM的diff和合并操作, 有性能提升
  • 没有Model的复杂关系, 编写应用逻辑非常清晰
  • 服务端渲染

关于React.js的中文介绍可以参考React.js概览。文中还指出FLUX对MVC做了调整:由原来的数据双向绑定改成了单向的一个循环。双向绑定会导致串联的更新, 一个对象改变导致另一个改变, 这还可能触发更多更新,当应用规模增加, 这些串联的更新使得用户操作结果改变了什么很难预测,而当更新只在单个回路上更新数据, 这个系统整体上就更容易预测了。

Browserify介绍

我们知道在node.js的包管理器npm上有很多精彩的代码,但Nodejs毕竟代表着后端,有什么工具能把那些代码用到前端呢?答案是browserify。

browserify
使用browserify,我们就能把一些node的核心模块和npm上成千上万的模块搬到前端。
我们还可以把node.js里的require方法用在前端js中。

Browserify安装

npm install -g browserify

代码示例

创建index.js文件,把上面的代码写入index.js文件中。
用browserify编译index.js文件到bundle.js
browserify index.js > bundle.js
创建index.html

在index.html中,引入刚才生成的bundle.js文件。
这样我们就把node模块和require用到了浏览器端了。
打开页面,查看控制台,我们可以看到控制台里输出了tell me how to use browserify。 Continue reading →

前端自动化工具Gulp

如今前端提到构建工具会自然想起Grunt,Grunt.js是基于Node.js的自动化任务运行器。去年Fractal公司发布了一个新的构建系统Gulp,希望能够取其精华,并取代Grunt,成为最流行的JavaScript任务运行器。

gulp

你可以使用Gulp及其插件对你的项目代码进行编译,还可以压缩你的js和css代码,甚至压缩你的图片等。Gulp和Grunt一样是用Node.js写的,所以你需要在你的终端上安装好Node.js,然后使用Node.js的npm包管理器安装Gulp。

安装

gulp安装命令
npm install -g gulp
在根目录下新建package.json文件
npm init .
安装插件包
npm install gulp gulp-browserify --save-dev
Continue reading →

What happend about Angular2.0

前几天听到朋友说,可以不用看angular了,angular2.0的改动是颠覆性的,出于好奇看了angular2.0的视频介绍。

Angular 2.0 Core
Angular 2.0 Core by Igor Minar & Tobias Bosch

首先我们来看看Angular1和Angular2在语法上的区别:

AngularJS-1.3 AngularJS-2.0

可以看到原来的ng-controller、ng-model、ng-click等关键词都替换成了使用括号的属性。右边则是表达式。视频里讲到了Properties & Attributes的区别,之前我一直分不清这两这到底有什么区别,现在算是明白了,引用原话解释:

All elements have properties and some properties are serializable into attributes and those that are always restricted(受限制的) to using just a string type.
So we find properties to be more flexible because they have different types and usually the API surface is bigger.

为什么说angular的改变是颠覆性的,来看看下面几张图,相信看完后你会吐血

controllers killed Continue reading →

工欲善其事,必先利其器

混迹前端已有五年多了,工作重心由最初的切图写页面转向专门写js交互,我深感js博大精深。
做web前端这行其实并不那么容易,原因大致三点:一是前端涉及的面太广,每个知识面都可以进行深入研究;二是前端技术比较开放,各种新技术层出不穷,学习成本很大;三是前端面向用户操作界面,必须得很好地适应各种设备。
以前的开发状态挺糟的,即便学到一些新技术也没精力和时间使用到项目中去。辞职了一段时间后,我开始把以前接触到的,听说过的捋了一遍,体会到了很多新技术带来的便利。
我们前端大致进行的工作是这么一些:

  • 监听请求,对路由进行判断
  • 解读请求,进行数据操作
  • 渲染页面或者API,返回给客户端

开发时都会有一套前端的基础架构:

  • 开发环境
  • 平台工具(框架、库、发布工具等)
  • 相应的开发规范
  • UI组件库
  • 开发文档

每个人的时间都很有限,我们不要重复造轮。这里我介绍一些常见框架和库并把他们分组罗列出来,每个工具都有他具体的职责,了解并组合使用将会大大提高前端的开发效率:

Bower    A package manager for the web
Grunt    The JavaScript Task Runner
gulp    the streaming build system
Yeoman    The web’s scaffolding tool for modern webapps

AngularJs    Superheroic JavaScript MVW Framework
Backbone    a light MVC App framework
Knockout    Simplify dynamic JavaScript UIs with ths Model-View-View Model (MVVM) pattern
ReactJS    A JavaScript library for building user interfaces
Flux An application architecture for React utilizing a unidirectional data flow

Underscore    a JavaScript library that provides a whole mess of useful functional programming helpers without extending any built-in objects
lodash    A JavaScript utility library delivering consistency, modularity, performance, & extras

CoffeeScript    a little language that compiles into JavaScript
Jade    a template language
Ractive.js    a template-driven UI library

AMD(Asynchronous module definition) a JavaScript specification that defines an API for defining code modules and their dependencies, and loading them asynchronously if desired
CommonJS    a group with a goal of building up the JavaScript ecosystem
RequireJS、seaJS a JavaScript file and module loader
Browserify lets you require(‘modules’) in the browser by bundling up all of your dependencies

Sass、Less    CSS preprocessor language
Modernizr    a JavaScript library that detects HTML5 and CSS3 features in the user’s browser

众多工具的产生使得前端能够进行模块化开发,每个模块高度解耦,使得系统更易维护。关于模块化开发网上的文章已有很多,这里不再赘述。来说说DSL,DSL指的是领域特定语言,它可以是内部的(使用宿主语言的语法,比如不使用JSX的ReactJS(属于内部DSLs)),也可以是外部的(使用和宿主语言不同的语法,比如本例中在JavaScript内部编写的内联 CSS(属于外部DSLs))。很多时候会被一些库里的语法迷惑,比如CoffeeScript,他属于内部DSLs,会将类似Ruby的语法编译成Javascript。当然任何工具都是有两面性的,编译意味着需要消耗性能,这是无法避免的事情。所以用不用,用哪种工具纯粹是个人喜好问题。