本文是『horseshoe·React专题』系列文章之一,后续会有更多专题推出
来我的
GitHub repo 阅读完整的专题文章来我的
个人博客 获得无与伦比的阅读体验
什么是UI?
如果你指的是布局和色彩,那更偏向于设计师的工作。
在现代web领域,大家已经有一个共识:UI是状态的演进。
那么什么是状态(state)?
现代网页往往意味着大量的人机交互,每一次交互都会产生一些数据,这些数据或者放在内存中,网页关闭即销毁,或者发送给服务器永久保存。但无论怎么样,这些数据都是前端要处理的。
带有时间性的交互数据,就是状态。
当页面初始化完成,变化的只有状态,所以我们才说UI是状态的演进。
现代前端框架的使命就是:开发者管理状态,框架根据状态自动生成UI。
首先我们明确一点,状态和UI是一一对应的。
只要状态发生改变,就需要一套新的UI和它匹配。
这就引出了现代前端框架的核心:如何去监控应用的状态?
Angular
Angular的哲学是监控状态发生改变的所有出口。
这种方式简单粗暴。
如果发现商场里有在逃通缉犯,那就调动警力封锁所有的出口,逃犯总不可能在商场里过日子。
而且Angular还惊喜的发现其实出口总共没几个。event回调,http回调,timer回调,promise回调,大概就这些了。
那么如何监控这些出口呢?
狸猫换太子,对这些任务做一层封装,开发者调用的实际上是被Angular动过手脚的方法。刚刚说什么来着?相当暴力。大家应该都听说过大名鼎鼎的zone.js
吧,它就是Angular所谓脏检查的基础设施。
不过Angular已经日薄西山了。陡峭的学习曲线,臃肿的代码库,一代和二代的完全不兼容,注定它要被开发者抛弃。
Vue
Vue的哲学是监控变量。
变量实际上是状态的容器,无论状态怎么变,最后都要装到变量这个坛子里。
Vue也觉得调动警力实施封锁实在是太粗暴了,现代社会的命脉是什么?是金融啊喂!
我只要监控逃犯的金融账户,就不怕他不消费。掌握他的行踪,实施定点抓捕就可以了。
那么如何监控变量呢?
JavaScript底层有实现,通过Object.defineProperty
接口的getter
和setter
,可以轻易监控变量的读取和更新。当然ES6开放了更加强大的Reflect
和Proxy
接口。
具体操作呢,在初始化阶段,Vue会把挂在UI上的变量都读一遍,触发getter
,然后getter
会为每个变量维护一个数组(因为一个变量可能被多次应用于UI),变量以及对应的回调被绑在一起push进数组里。每次开发者更新变量的值就会触发setter
,setter
的作用就是执行回调。当然,回调里就是更新UI的动作。
某种程度上说,Vue脱胎于Angular,它带着Angular的遗志,将来是要和React决战光明顶的。
Vue没有让人失望,现在已经是一枚当红流量小生了。
React
React的哲学是监控DOM的镜像。
人海茫茫抓捕逃犯成本不是高嘛,我们有监控摄像头啊!无数的摄像头基本可以拼凑出一个公共场所的副本,依靠这个副本,警方可以随心所欲的对比、回放、分析,而不需要顾虑部署警力的成本。
React的思路非常奇特,既然框架负责自动更新UI,那UI就应该成为框架的一部分。
现在UI成了框架的画板,开发者在画板上自由作画,阶段性完工后再由React一次性挂到界面上。
这就带来了一个问题:DOM是好惹的吗?这么不尊重它,每次innerHTML
了事?
React必须解决这个问题,而它的方案是抽象UI(一般称为Virtual DOM)。
当我们说div是一个元素的时候,我们指的不是那个标签,而是与之关联的一个对象,这个对象描述了div的位置和功能,依据这个对象我们是可以复原出一个DOM节点出来的。
可React觉得这个对象还是太臃肿了,对象里只需要包含必要信息即可,于是React提取必要信息构建了一份DOM的镜像。
什么是必要信息呢?对一个节点而言,它的标签类型、属性、子节点引用就是必要信息,无数节点确立其位置就形成了一个树结构,这个树结构和DOM是一一对应的。
当状态更新的时候,React便获得了两份镜像,通过对比这两份镜像,React就可以给UI打补丁,而不是完全覆盖旧的UI了。
React做的事情特别纯粹,你手里有一幅画,你可以在画上作任意更改,React的使命就是在合适的时机将你的更改生成一幅新的画。
为什么是React
如果说Angular手里握有足够的警力,Vue手里握有金融命脉,那么React手里握有的是整个地图,这他妈不是开挂了么!
当然,框架之间不能这样简单的去对比,但是对开发者而言,在React架构下,状态的层次感变得异常清晰。
我们已经同意状态是现代网页的核心,也同意UI是状态的演进,那么清晰的状态层次感和开发者对UI足够的掌控力(幻觉),会给开发者一种莫名的秩序感,这种秩序感才是React备受开发者喜爱的根本原因吧(不接受异议)。
你看,我在画板上作画哟,真的是我在作画哟。
除此之外,React真正的以组件为核心,HTML和CSS都纳入到组件中来,也是它备受开发者喜爱的原因之一。
除此之外,React把UI抽象出来,理论上可以应用到任何界面,也是它备受开发者喜爱的原因之一。
除此之外,JSX的不伦不类,额…是开发者需要克服的心理障碍。
React专题一览