You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
HTML+CSS+JS+jQuery spaghetti: 面条式代码。一个需求,到处改动。根据页面变动的地方,找到其 id/selector,修改所有与其相关的 handler、样式、逻辑。这种组织,所有组件都依赖于 dom 元素的一个 id,也决定了 DOM API 的操作方式
MV*(P or C):然后这时就开始分离关注点了。分离是怎么分离呢,就是人为划分出一个数据 model、展示 view 的概念,然后把其他所有的都划归为 controller 或 presentor。这是初步的 SOC,结果就是,数据和视图之间不能直接接触,事件发生后,由 controller 从 model 中拿数据,处理后结果反映到 model 中去,并通知 view 使用新的 model 更新页面,也即是 model 和 view 分别作为数据和展示的 single source of truth,所有控制(比如获取并处理 model、通知 view 等)类的工作全部揉到控制器中做。这其实只是上个阶段代码的重新组织,但也不是毫无进步。数据的这层解耦,使得一大部分数据的获取不再需要去 dom 中取;但本质上,只是把 jQuery way of working 中的5步划分了责任:getData 给 model 做,callAPI 给 controller 做,并负责通知 view 做 recalculateStyle、renderDOM 和 renderCSSOM 的操作。并未改变 VC 仍然需要通过全局的 html-selector 获取 HTML 元素进行所有后续操作的本质
http://todomvc.com/
把这个视频再看一下,感受下这个演进:https://classroom.udacity.com/nanodegrees/nd001-cn-advanced/parts/7cfc9f99-e827-4ed3-8e13-126f6b0f3998/modules/59e5bbe2-0738-4654-ba6b-fd0feaa632de/lessons/3417188540/concepts/33916789400923
前端开发模式 发展简史
getData
给 model 做,callAPI
给 controller 做,并负责通知 view 做recalculateStyle
、renderDOM
和renderCSSOM
的操作。并未改变 VC 仍然需要通过全局的 html-selector 获取 HTML 元素进行所有后续操作的本质data-bind
(Knockout.js)、v-if
(Vue.js)、JSX(React)、ng-app
(Angular 1.x))、变化检测(脏检查、VirtualDOM)等。这个使你的handler
真正地能专注于业务处理、数据改变即可,数据你也不需获取,就在你自己控制下,反过来是框架来监测你的数据;数据改变后,你也不需要手动通知视图了,框架会帮你通知到特定的 HTML 元素上并做更新;更新视图时,你也不需要通过 jQuery 提供 html-selector 了,框架会用你所使用的 html-anchor 来追踪到你真正需要更新的 html view 上。可以说,这个阶段 通过声明式解决了全局的 html-selector 问题,通过双向绑定解决了对视图的手动通知,让开发者可以真正专注在业务开发上。简直伟大的设计,演变到这里,基本就是近代前端框架的能力所在了,代表作有 Knockout / Backbone / Angular 1 等。但是不是到这里就没有继续发展了呢?当然不是,否则「现代」框架提法哪里来import/export
应该是完美解决方案,可惜目前还没有原生实现,不过能通过 babel 使用也很满足了。除此之外,很多框架提供了自己框架特定的解决方案,比如labjs
,angular
自带的module
机制等。严格来说,模块化是整个 JS 领域发展的潮流,是 JS 代码的组织方式,不特定于框架,因此它应该算是一波独立的浪潮,与前端应用的框架没有紧耦合的联系jQuery 操作模式
可以看到这个模式的短板在哪里?
handlers
都是全局绑定!原生的 JS+jQuery 是没有模块的。再说,JS 应该无法提供对 HTML 的模块化;只能通过模块化方案来解决;handler
需要自己处理数据搜集、API 调用、更新页面、更新样式等操作。实际上,真正业务发生的地方,只有 API 部分,更新页面和样式只不过是显示问题。在核心业务的 API 部分,它无法做到类似 redux reducer 这样纯净的 API:nextState = reducer(prevState, action)
现代前端框架 解决方案
写完前面的前端发展简史,我们应该就能发现,近现代框架进入前的 jQuery 时代有两个问题:无法分离的关注点,以及全局的 html-selector。前者主要是体现在,一个 event handler 需要处理多如 获取数据、业务逻辑、API 调用、更新视图、更新样式 等事务;后者主要是体现在一个 selector 是绑定到全局作用域下的,代码会污染全局环境。近现代框架提供的解决方案,主要即是解决了这两个问题。
无法分离的关注点一问,
在 MV* 和组件化的关系上,徐飞蜀黍讲,框架在做分层(就是我理解的 MVC、MVVM 等分层)的过程中其实推动了代码的组件化。
复杂性管理
有 JS+ES6 是不够的,你需要组织文件,以反映需求变动的结构。我觉得「设计」的难点在于二:一是敏锐发现需求变动实际变的是哪个点,把它 SRP 出来;二是衡量设计好坏。
复杂性是不会凭空消失的,它只是从其中一处转移到另一处。对于设计评判,即看对于特定场景,该设计是否减少了复杂度。也即,复杂度是否正确地被转移到了框架内部,这取决于场景下的痛点是否客观存在,框架定位是否准确。
库和框架的区别?争论不休,有三点不错:
组件化、模块化的关系是什么?提前设计的好处?提前设计的度?如何设计?
库和框架的问题:
The text was updated successfully, but these errors were encountered: