郭 蕊 赵元苏
(北京工业职业技术学院 电气与信息工程学院,北京 100042)
随着互联互通的快速发展,Web应用不断推陈出新,Web前端技术发挥着举足轻重的作用。如今智能化设备全面普及使得Web前端页面越来越复杂,从视觉体验到对用户的友好交互、技术特效等的要求越来越高,系统的维护要求不断提升。前端技术的不断演进,也带来了前端开发模式的不断改进,在基于前端开发逐渐趋于复杂性的背景下,Web前端框架技术也成了人们关注的焦点。大多数的Web框架提供了一套开发和部署网站的方式,实现了数据的交互和业务功能的完善。开发者使用Web框架只需要考虑业务逻辑,因此可以有效地提高开发效率。
在Web发展早期,页面的展示完全由后端PHP,JSP控制。Ajax技术的出现给用户带来了新的体验,前后端通过Ajax接口进行交互,分工逐渐清晰,伴随着JavaScript技术的革新[1],浏览器端的JavaScript代替了服务器端的JSP页面,其可以依靠JavaScript处理前端复杂的业务逻辑,但是代码的复杂度仍然很高,因此为了提升开发效率,简化代码,便于后期维护,在开发中应用分层的架构模型应运而生。
MVC(Model View Controller)框架模式即为模型(Model)、视图(View)和控制器(Controller)的分层模式。模型层用于处理数据的部分,能够直接针对相关数据进行访问,针对应用程序业务逻辑的相关数据进行封装处理;视图层能够显示网页,由于视图层没有程序逻辑,因此需要对数据模型进行监视和访问;控制层主要体现在对应用程序流程的控制,以及对事件的处理和响应上。控制层能够获取用户事件信息,通知模型层进行更新处理,由模型层将处理结果发送给视图层,视图层的相关显示信息随之发生改变,因此控制层对于视图层以及模型层的一致性进行了有效的调节和控制[2]。
下面以用户提交表单为例,展示MVC的设计模式。MVC模式示意图如图1所示。
图1 MVC模式示意图
在图1中,当用户提交表单时,控制器接收到HTTP请求,向模型发送数据,模型调用数据将数据返回至控制器,控制器调用视图将处理结果发送至浏览器,浏览器负责网页的渲染。
前端MVC模式中最为广泛的框架为Backbone.js,Ember.js等。Backbone.js的优势在于可以较好地解决系统应用中的层次问题,同时应用层中的视图层在模型数据修改后,可及时对自身页面数据进行修改,此外可通过定位有效地找到事件源头,解决相关问题。Ember.js广泛应用于桌面开发中,借助于该框架的优势,能够实现模块化、标准化的页面设计与分类,达到MVC运行的效率。除此之外,Ember.js框架能够有效地结合大数据系统的优势,将整个运行过程中所产生的各种参数及时、有效地记录在档案数据库中。
MVC模式最早应用于桌面应用程序中,随着Web前端的发展,复杂程度逐渐增加,MVC模式被广泛应用于后端的开发,实现数据层与表示层分离。作为早期的框架模式,MVC模式主要的优势在于能够清晰地分离视图和业务逻辑,满足不同用户的访问需求,在一定程度上降低了设计大型Web应用的难度。但是由于内部原理较为复杂,并且定义不够明确,因此开发者需要明确前端MVC框架的使用范围,并且需要耗费大量的时间和精力解决MVC模式运用到应用程序的问题。另外,MVC严格的分离模式也导致每个构件均需要经过彻底的测试才能使用,使得在相当长的一段时间内,MVC模式不适用于中小型项目。随着技术的发展,部分框架能够直接对MVC提供支持,但是在实现多用户界面的大型Web的应用上,开发者仍需要花费较大的工作量[3],不利于开发效率的提升。
MVP(Model-View-Presenter)模式是由IBM公司于2000年开发的一种模式,是MVC模式的改进,主要用来隔离UI,UI逻辑和业务逻辑数据,旨在使Web应用程序分层和提高测试效率。其中,Model提供数据,View负责显示,Presenter负责逻辑的处理,其通过接口与View通信的界面逻辑组件。在MVP模式中,首先,View与Model完全隔离,使得模型层的业务逻辑具备了较好的灵活性。其次,Presenter与View的具体实现无关,应用可以在同一个模型层适配多种技术并构建视图层。同时,由于View和Model没有直接关系,因此MVP模式可以进行View的模拟测试。
MVP模式和MVC模式都具有相同的分层架构设计,均由视图进行显示,模型管理数据;而它们的区别是:在MVP中,视图和模型之间的通信是通过Presenter进行的,所有的交互都发生在Presenter内部,而在MVC中,View直接从Model中读取数据而不是通过Controller[4]。由于MVP模式中的View和Model层之间没有关系,因此,可以将View层抽离为组件,在复用性上比MVC模型具有优势。
作为MVC模式的演变,MVP模式主要是为了解决MVC模式中View对Model的依赖。MVP模式的优点在于模型和视图完全分离,开发者可以只修改视图而不影响模型,且可以更高效地使用模型。同时,由于所有的交互都在Presenter内部完成,因此可以更高效地应用模型,另外可以脱离用户接口测试业务逻辑。其劣势在于View和Presenter的接口使用量较大,使得视图和Presenter的交互过于频繁。在用户界面较为复杂的情况下,一旦View发生改变,View和Presenter之间的接口必然发生变更,导致接口群的需求量增加,因此适用于开发后期需要不断维护且较大型的项目。
MVVM(Model View ViewModel)为Model(模型)-View(视图)-ViewModel(视图模型)框架模式,其结构如图2所示。
图2 MVVM模式示意图
MVVM模式的出现是为了解决MVP模式中,由于UI种类变化频繁导致接口不断增加的问题。其设计思想是“数据驱动界面”,以数据为核心,使视图处于从属地位。该模式只需要声明视图和模型的对应关系,数据绑定由视图模型完成,相当于MVC模式的控制器,实现了视图和模型之间的自动同步。
MVVM模式简化了MVC和MVP模式,不仅解决了MVC和MVP模式中存在的数据频繁更新的问题,同时使界面与业务之间的依赖程度降低。在该模式中,视图模型、模型和视图彼此独立,视图察觉不到模型的存在,这种低耦合的设计模式具有以下优势:
(1)低耦合。View可以不随Model的变化而修改,一个ViewModel可以绑定到不同的View上,当View变化的时候,Model可以不变;当Model变化的时候,View也可以不变。
(2)可重用性。将视图逻辑放在ViewModel,View将重用视图逻辑。
(3)独立开发。开发人员可以专注于业务逻辑和数据的开发,设计人员可以专注于界面的设计。
(4)可测试性。可以针对ViewModel对View进行测试。
MVVM框架模式是MVC精心优化后的结果,适合编写大型Web应用。在开发层面,由于View与ViewModel之间的低耦合关系,使得开发团队分工明确而相互之间不受影响,从而提升开发效率;在架构层面,由于模块间的低耦合关系,使得模块间相互依赖性降低,项目架构更稳定,扩展性更强;在代码层面,通过合理地规划封装,可提高代码的重用性,使整个逻辑结构更为简洁[5]。
MVVM模式中应用较为广泛的框架有AngularJS,React,Vue.js,笔者重点对MVVM模式的主流框架进行分析。
AngularJS框架是Google公司于2009年发布的一款MVVM模式的框架,具有双向数据绑定,模块化,依赖注入、组件、管道、模板驱动等特征。在AngularJS中,模型和视图模型通过$scope对象互动,模型不包含相关逻辑。通过$http获取服务器端的数据,依靠模块依赖实现数据共享。另外AngularJS内含丰富的内置指令,可以减少代码量,实现购物车、商品列表等,自定义指令和服务有效地提高了代码的复用性。另外,由于内部嵌入了jQLite,使得由JavaScript控制视图模型变得简单,对于用户的交互事件,则利用$scope的行为逻辑,通过视图模型来改变模型,通过$scope的“脏检查机制”更新到View,进而实现了视图和模型的分离。
AngularJS使得开发现代的单一页面应用程序(Single Page Applications,SPAs)变得更加容易。总的来说,AngularJS为程序开发者提供了以下便利:把应用程序数据绑定到HTML元素,可以克隆和重复HTML元素,可以隐藏和显示HTML元素,可以在 HTML元素“背后”添加代码,支持输入验证。
React框架由FaceBook内部团队开发,于2013年5月开源。React问世后,其单页面应用、虚拟DOM、高性能、组件化、单向数据流等特点是对整个前端领域的颠覆。在React中所提及的页面,均由组件构成,实现逻辑由JS动态生成。组件化的设计也充分体现了低耦合性能,最大限度地实现了高可复用性。
在React中采用虚拟DOM原理,通过JSX语法绘制出来的元素只是一种类似DOM的数据结构,并不是真正的DOM,这种原理大大减少了DOM节点操作频率,优化了性能,另外React中数据流是单向的,数据通过组件props和state层层向下传递,如果要添加反向数据流,则需要通过父组件将回调函数传递给子组件。每当状态更新时,触发回调,父组件调用setState重新渲染页面。
Vue.js于2014年发布,是一款友好的、多用途且高性能的JavaScript框架,采用MVVM模式。其能够帮助创建可维护性和可测试性更强的代码,是目前所有主流框架中学习曲线最平缓的框架。Vue.js框架是渐进式的,所谓的渐进式是指框架分层,最核心的部分是视图层渲染,向外依次为组件机制、路由机制、状态管理和构建工具。Vue.js有足够的灵活性来适应不同的需求,除了引入虚拟DOM外,还提供支持JSX和TypeScript,支持流式服务端渲染,提供了跨平台的能力等特征,很适合搭建类似于网页版知乎这种表单项繁多,且内容需要根据用户的操作进行修改的网页版应用。
Vue.js框架与Angular.js框架有很多相似之处,例如,数据双向绑定、指令、路由等,均可以开发单页面应用。但是,两者在数据双向绑定上,实现方式有所不同,由于Angular.js的脏检查机制导致,监听的数据越多,绑定实现得越慢;而Vue.js的数据劫持方式速度会快很多,只要监测到数据发生变化就会更新视图,尤其在数据增加时,Vue.js框架的优势更加明显[6]。
Vue.js框架与React框架相比,均使用了虚拟DOM,提供了响应式和组件化的视图组件,将注意力集中保持在核心库,而将其他功能如路由和全局状态管理交给相关的库。
Vue和React的区别在于:(1)React组件的变化会导致重新渲染整个组件子树,而Vue系统能确定具体需要被渲染的组件,开发者不需要考虑组件渲染的优化;(2)React一切都是JavaScript,所有组件的渲染功能都依靠JSX,而Vue.js有自带的渲染函数,支持JSX,并且可以使用官方推荐的模板渲染视图;(3)React通过CSS-in-JS方案实现CSS作用域,而Vue.js则是通过为style标签加scoped标记实现;(4)React的路由库和状态管理库由社区维护,而Vue.js的路由库和状态管理库都是由官方维护并且支持与核心库的同步更新。
早期的Web前端主要包含HTML,CSS和JavaScript三大部分,其中HTML主要负责页面结构,CSS主要负责页面样式,JavaScript主要控制页面行为和用户交互,前端仅限于网页的设计,大部分功能需要依赖后端实现。随着Web应用的迅速发展,前端的功能性越来越强,开发难度逐渐增大。一大批优秀前端框架的出现推动了前端技术的发展,降低了开发成本,提升了开发效率。起初的JavaScript框架jQuery凭借便捷的DOM操作、支持组件选择、内部封装Ajax操作等特点占据着主导地位。但随着前端的进一步发展,利用jQuery开发Web应用,无法分离出业务逻辑、交互逻辑和UI设计,增加了代码的维护难度。MVVM设计模式的出现,实现了数据和视图的自动绑定,将DOM操作从业务代码中剥离,提高了代码的可维护性和复用性。
国外前端开发起步早于国内,涌现了较多的高水平Web框架,并且能够较好地支持移动端。目前,国内知名互联网公司致力于开发高水平的开源Web前端框架,总体水平已经达到了较高的程度。百度前端团队开发的QWrap突破了jQuery的局限,提供了原型功能,为广大用户带来了便利;腾讯非侵入式的JX前端框架,实现了JavaScript的扩展工具套件,于2012年切换到Github,具有较优的执行效率,无过度的封装,并且努力探索前端使用MVP,MVC等模式构建大型Web应用。淘宝内部使用的Web框架KISSY是一款跨终端、模块化、高性能、使用简单的JavaScript框架,具备较为完整的工具集以及面向对象、动态加载、性能优化的解决方案,为移动端的适配和优化做出了巨大贡献。
在互联网快速发展的今天,前端框架被广泛应用。为了适应网站的大量需求,加快开发网站的效率,大型互联网厂商纷纷构建满足各自业务的前端框架,如Element UI和Ant Design分别是“饿了么”和阿里巴巴自研的前端UI组件库。工具的发展和前端的发展相辅相成,JavaScript的每次进步都会带动浏览器厂商和相关开发工具的进步,同时也为浏览器的兼容性提出了更合理的解决办法。
前端框架技术的发展日趋成熟,未来前端在已经趋向成熟的技术方向上会慢慢稳定下来,进入技术迭代优化阶段,新的Web思想也会给前端带来新的技术革新和发展机遇。