1、SOFTWARE2023软 件第 44 卷 第 7 期2023 年Vol.44,No.7作者简介:马利军(1991),女,河南焦作人,本科,研究方向:计算机应用技术。Web 前端架构模式的演化及MVVM 模式在 Web 前端框架中的研究马利军(上海人大人创新创业研修学院,上海 200001)摘要:在程序设计领域,前端是指网站的前台部分,负责界面展示并处理用户交互。作为直接和用户打交道的部分,它的性能直接决定着用户的体验效果,而架构模式是影响整体应用性能、决定应用效果的关键着力点。本文梳理了 Web 前端架构模式的演化过程:“MVC 模式 MVP 模式 MVVM 模式”,立足当前主流前端框架 V
2、ue.js 使用的 MVVM 模式,分析了MVVM 架构模式在 Web 前端框架中的设计与实现思路,为 Web 开发者提供参考和借鉴。关键词:MVVM;Web;前端;Vue.js中图分类号:TP393.09 文献标识码:A DOI:10.3969/j.issn.1003-6970.2023.07.015本文著录格式:马利军.Web前端架构模式的演化及MVVM模式在Web前端框架中的研究J.软件,2023,44(07):061-065The Evolution of Web Front-end Architecture and the Research of MVVM Pattern in We
3、b Front-end FrameworkMA Lijun(Shanghai RDR Innovation&Entrepreneurship Training College,Shanghai 200001)【Abstract】:In the field of programming,the front end refers to the front part of the website,which is responsible for the display of user interface and handling users operation on webpage.As a par
4、t of dealing with users directly,its performance directly determine users experience,while the architecture pattern is the key point to affect the overall application performance and determine the application effect.This paper combs the evolution process of the Web front-end architecture pattern:MVC
5、 pattern MVP pattern MVVM pattern,and then based on the MVVM pattern applied by Vue.js,the current mainstream front-end framework,analyzes the design and implementation of MVVM architecture pattern in Web front-end framework,and provides reference for Web developers.【Key words】:MVVM;Web;front end;Vu
6、e.js设计研究与应用0 背景起初,Web 网页设计师在设计 GUI(图形用户界面)的时候,代码是杂乱无章的,没有架构模式可言。当时需要前端来实现的功能比较简单,网页设计以 HTML 为骨架,CSS 为外貌,JavaScript 为交互。2005 年 AJAX的出现,为前端提供了局部刷新页面的技术,使业界更加重视用户的交互,因此出现了各种对 DOM 进行操作的 JS 库,比如 jQuery。相比于原生 JavaScript API,这些 JS 库封装了 AJAX 交互接口,提供了更加方便的DOM 操作,同时也解决了浏览器兼容问题,前端生产力得到了极大的提高。但是当前端功能较多时,从后端获取的数
7、据和 HTML 展示,以及处理用户交互的代码夹杂在一起,后期进行项目维护或者增加新特性时难度很大。从抽象层面来讲,Web 前端开发一般包括模型、视图以及逻辑的开发,其中逻辑又分为应用逻辑、业务逻辑以及同步逻辑。举个例子来说,用户在视图(也就是UI 界面)上,通过键盘或者鼠标等操作会执行应用逻辑,应用逻辑则会触发业务逻辑,从而变更数据模型。而当数据模型变更的时候,还需要同步逻辑将数据模型的变更同步到 UI 界面上让用户感知到。可以发现模型、视图天然可以分层,然后就出现了 MVC、MVP、62软 件第 44 卷 第 7 期SOFTWAREMVVM 等设计模式来改进代码的组织方式。1 Web 前端架
8、构模式的演化在 MV 系列架构模式中,M 和 V 分别指 Model 层和View 层,Model 层是数据模型,用来存储数据;View 层是视图层,用来展示 Model 层的数据。在不同的模式中,虽然 Model 层和 View 层的内容会有所差别,但是其基础功能不变,变的只是数据的传输方式1。1.1 MVC(Model-View-Controller)随着前端技术的发展,终端设备性能和用户体验重要性的提升,越来越多的业务逻辑从后端向前端倾斜,前端应用开始变得复杂,所有代码混在一起的开发方式无疑是比较低效的。参照后端的主流架构模式,在Web 前端也出现了 MVC 模式。在前端自有的 MVC
9、架构中,前端系统由模型层、视图层、控制器层组成。模型层是数据层,它定义了系统中需要用到的数据以及对数据的处理方法,比如数据格式转换,通常它需要和后端的数据持久化层进行通信;视图层是用户可以看到并与之交互的界面,主要负责页面展示和事件响应,具体表现为:(1)将模型层的数据展示在 UI 界面;(2)当用户在界面进行鼠标点击或者键盘输入时,传递调用控制器层进行逻辑处理;控制器层则是模型层和视图层之间的纽带,负责一些业务逻辑的处理。从前端到服务端的整个架构来看,主要的业务处理逻辑依然在服务端,前端主要负责展示。前端的 MVC架构是对服务端 View 层次在客户端上的处理逻辑的进一步细化。MVC 模式对
10、于 Web 前端开发而言是一种十分有利的模式,各个层次职责明确,实现了代码层面的解耦,也便于后期的开发和维护。1.2 MVP(Model-View-Presenter)MVP是模型-视图-表示器,从MVC模式演变而来,由IBM的子公司Taligent提出。在MVP模式中,使用Presenter替代了Controller,同时改变了通信方向。在前端的 MVC 模式中,视图层监听到用户的交互操作后,传递调用控制器层进行逻辑处理,控制器层完成逻辑处理后,通知模型层进行数据更新,模型层更新数据并通知视图层更改 UI 界面供用户感知界面的变化2。但在MVP 中,模型层和视图层并不直接通信,而是通过表示器
11、层来进行间接通信。前端 MVC 模式是一个相互连接的三角形结构,而MVP 模式是一个上下垂直的层次结构。MVC 模式与MVP 模式的对比如图 1 所示。MVP 模式剥离了视图与数据模型的关系,视图可以从特定的业务场景中抽离,在复用性上比 MVC 架构好很多。但是由于视图层和模型层的所有交互都要通过表示器层来实现,致使表示器层要处理的逻辑越来越多,越来越难以维护。而且用户的交互操作导致的模型层和视图层数据状态的同步工作都需要表示器层进行“手动”同步,代码量大,还是有比较多的冗余部分,主要表现为 DOM 操作,为后期的代码维护增加了一些难度。1.3 MVVM(Model-View-ViewMode
12、l)MVVM 是模型-视图-视图模型,是 MVP 模式的进一步改进,最早在 2005 年由微软的工程师提出。其中模型层代表数据模型,视图层代表 UI 组件,而视图模型层,则是 MVVM 的核心,主要负责视图层数据和模型层数据的同步工作。它实现了数据的双向绑定,即当模型层中的数据状态发生改变时,会通知视图层进行界面更新,而当用户操作视图界面,视图模型层也能监听到视图层的变化,然后通知模型层进行同步更新,从而避免了 MVP 框架中“手动”进行数据同步的繁琐操作,使得数据处理更加方便了,即只需告诉视图层展示的数据是模型层中的哪一部分即可3。KnockoutJS 是最早实现 MVVM 模式的前端框架之
13、一。当下,MVVM 模式已经相当成熟,主流的前端框架中 Angular、Vue 也是基于 MVVM 模式的,而且Vue.js 可以说是 MVVM 架构的最佳实践,下面简单分析下 Vue 中的 MVVM。如图 2 所示,Vue 中的 MVVM 也是由模型、视图、视图模型组成:(1)模型层。可以把模型理解为数据层,是一个纯JavaScript 对象,用于保存一些数据,它对应后端的数据模型。(2)视图层。作为视图模板存在,在 MVVM 中整个视图层就是一个动态模板。除了用于定义结构和布局之外,它还展示了模型层的数据。视图层并不负责数据ViewControllerModelModelViewPrese
14、nterMVCMVP图 1 Web 前端的 MVC 模式 VS MVP 模式Fig.1 MVC mode VS MVP mode on the Web front end63马利军:Web 前端架构模式的演化及 MVVM 模式在 Web 前端框架中的研究状态的实际处理,只是做:数据绑定声明、指令声明、事件绑定声明。(3)视图模型层。视图模型层,作为视图层和模型层之间连接的桥梁,主要负责视图层和数据层的数据同步。视图模型层可以做到从模型层中取出数据,然后渲染在 UI 界面,也能做到监听视图上的 DOM 事件,当用户触发事件之后,进行相应的处理,实现了数据的双向绑定。所谓数据的双向绑定,其实是和单
15、向绑定对应的。我们知道,在 React.js 中是单向绑定,即把数据绑定到视图。这样当我们通过 JS 代码修改数据的时候,就可以实现视图的自动更新。而 Vue.js 中的双向绑定,指的是在把数据绑定到视图的同时,也将视图的更改绑定到数据,这样当我们通过 JS 代码修改数据的时候,就可以实现视图的自动更新,反之,当用户更新了视图,对应的数据也能自动更新。它的实现方式是:1)数据到视图的方向:当模型层的数据有更新时,Data Bindings 工具会自动更新页面中的 DOM 元素;2)视图到数据方向,当用户在界面进行操作时,例如对 input 框进行输入,DOM Listeners 工具会检测到D
16、OM 事件,并将 DOM 事件产生的数据变化传递给模型层,同步更改模型层数据。通过以上分析,我们知道在 MVVM 模式下,数据层和视图层之间虽然没有联系,但是可以通过视图模型层进行交互。交互是双向的,同时还是自动的,无需人为干涉,视图层与数据层之间的双向状态维护由视图模型层来统一管理,框架自动管理交互操作,从而将视图 UI 渲染逻辑和业务逻辑分开,解放了大量的内容渲染和事件绑定的 DOM 操作逻辑,使开发人员能够更多的关注业务逻辑,在提升开发效率、保证开发质量的同时,页面渲染性能也有了很大的提升。2 Vue 中 MVVM 模式的实现原理上述简单介绍了什么是 MVVM,接下来以 Vue 为例介绍
17、 MVVM 的实现原理。为了便于说明原理和实现,此处对 Vue2 源码中的思路进行了一些简化和改造。我们知道,MVVM 的核心层是视图模型层,它实现了数据层和视图层的双向绑定。而 Vue 中,主要是通过数据劫持并结合发布-订阅模式来实现数据的双向绑定的。2.1 关键概念在分析 Vue 中双向绑定的实现原理之前,我们需要先了解以下几个概念,以便于对后面内容的理解。2.1.1 发布-订阅模式发布-订阅模式是一种消息传播模式,该模式包含发布者和订阅者两种角色,它们之间不直接联系,而是通过调度中心关联起来。具体流程如下:订阅者通过调度中心订阅某个主题发布者发布通知调度中心收到通知并推送给订阅者订阅者执
18、行相应的操作。在发布-订阅模式下,一个对象的状态发生了变化,那么所有订阅它的对象都将收到这个消息,即它定义了对象之间一对多的依赖关系。本质上,发布者是否发布,订阅者是无感的,只有发布者发布的内容是订阅者订阅的主题,订阅者才会收到通知。这种模式带来的最大好处是代码上的解耦。发布者不关心主题的订阅者,只需要在适当的时候发布相应的主题即可,而订阅者则依赖于主题,而非主题的发布者。发布-订阅模式非常适合 MVVM 模式中数据绑定的实现。在 Vue2 的源码中,每个组件实例都可以看作是一个订阅者,它会在初始化渲染组件的时候,循环遍历传入的 Property 属性,把自己加入到对应属性的订阅者列表,这样当
19、对应属性有更新时,就会收到通知,从而更新视图。2.1.2 数据劫持数据劫持,是针对 Object 类型的数据而言的,它指的是劫持对象的属性的读取或者修改操作。通俗来讲,数据劫持就是在获取对象的属性或者给对象的属性赋值之前,动一些手脚做点我们自己想做的事情,也就是所谓的“劫持”操作。Vue2 中是通过 Object.defineProperty 实现数据劫持,该方法接受三个参数:第一个参数是被劫持的对象;第二个参数是被劫持的对象的属性;第三个参数是一个配置项对象(包括:value、enumerable、configurable、get 和 set 等几个属性),具体使用方法如下:var vm=;
20、Object.defineProperty(vm,a,enumerable:true,configurable:true,get()/dependency collection and return the value图 2 Vue 中的 MVVMFig.2 MVVM in VueModelViewViewModelDOM ListenersData Bindings64软 件第 44 卷 第 7 期SOFTWARE,set(newVal)/notify subscriber to update)数据劫持,主要就是用到了 get 和 set 两个属性。通过该方法,被劫持的对象 vm 的属性 a
21、,只要在外界获取(vm.a)或者修改属性值(vm.a=1)的时候,都会触发get 或者 set 方法,这样我们就可以在 get 或者 set 函数里面做一些额外的劫持操作。这些额外的劫持操作其实就是利用发布订阅模式,对数据属性的依赖项(也叫订阅者)进行收集,在数据属性的值有变动时,通知订阅者做相应的更新。2.1.3 模板解析我们知道 Vue 中是通过数据绑定声明(大胡子语法的表达式)、指令声明(v-model,v-html,v-text等)和事件绑定声明(v-on)来实现数据绑定和事件监听的,而浏览器并不能识别这些指令和语法,因此在加载页面后,需要将这些语法转换成真正的数据呈现给用户,这就是模
22、板解析所做的工作。2.1.4 依赖收集依赖收集是发布-订阅模式的流程中的一个环节。在发布-订阅模式中,订阅者要先通过调度中心订阅某个主题。那么在调度中心内部,对于该主题,就会维护一个订阅者列表,用来保存所有订阅了该主题的订阅者。收集订阅者的过程就是依赖收集。2.2 实现原理总的来说,MVVM 在 Vue 中的实现思路是:首先使用数据劫持的相关技术,对数据的变化进行监听。同时引入发布-订阅模式,完成对属性依赖项的管理;然后进行模板解析,将模板中的指令和表达式替换为真实数据;最后初始化渲染页面。模板和数据通过 Watcher进行连接,这样数据的变化直接映射到视图,同时需要监听视图上的输入等相关事件
23、,这样当输入变化时,直接映射到数据模型。具体实现步骤如图 3 所示。(1)实现一个 Observer 数据监听器,对数据进行监听,当数据变更时通知视图更新。Vue2 中使用 Object.defineProperty 来监听属性值的变动。对于要监听的 JS 对象,Vue 将遍历它的属性,包括子属性对象的属性,将它们转为 getter/setter,实现对数据的监听,当监听的属性发生变动时,然后通知订阅者执行对应的更新函数。对数据的监听,还需要实现一个 Dep 依赖收集器。依赖收集器,也叫消息订阅器,用于对属性进行依赖收集和通知用到属性的地方进行同步更新。依赖收集器的内部维护一个数组,用来收集订
24、阅者。依赖收集器通过发布-订阅模式来关联数据状态(属性)和 Watcher 实例(订阅者)。收集订阅者的时机是初始化模板渲染的时候。在初始化渲染模板的时候,对每一个与数据绑定相关的节点都生成订阅者,绑定对应的更新函数,这样才能在数据变动时收到通知,更新视图。具体做法是:在 Watcher 实例化(也就是生成订阅者)的时候,在构造函数中执行一行获取对应属性的值的代码,从而触发对应属性的 getter 函数,然后将 Watcher 实例添加到依赖收集器中。(2)实现一个 Compile 模板编译器,负责对模板中的指令和表达式进行解析。首先,将当前根节点的所有子节点取出,添加到一个新建的 Fragm
25、ent 对象中;然后,对 Fragment 对象中的所有层次的子节点递归进行解析,用真实的数据new MVVM()Observer数据劫持Compile模板编译ViewDepWatcher通知数据变化通知订阅者更新添加订阅者订阅数据变化,绑定更新回调执行更新回调,更新视图初始化视图图 3 MVVM 的实现原理Fig.3 Implementation of MVVM65马利军:Web 前端架构模式的演化及 MVVM 模式在 Web 前端框架中的研究替换模板中的表达式;最后给事件指令节点添加事件监听,给非事件指令的表达式添加数据的订阅者,订阅模板中数据的变更,对于模板中的数据所对应的节点绑定好更新
26、界面的函数,当收到数据变更的通知时,执行对应的更新函数,更新界面。具体包括:1)对文本节点(插值表达式)进行解析;2)对元素节点的指令属性进行解析:事件指令解析和一般指令解析;3)最后,将编译的内容回写到真实 DOM 上。(3)实现一个 Watcher,用于对属性进行监听,并实现属性值的同步更新。在模板编译的过程中,会为每一个与数据绑定相关的节点生成一个订阅者 Watcher,让 Dep 添加当前Watcher,在接收到数据变更的时候,及时通知订阅者进行更新。(4)实现 MVVM。初始化 MVVM 构造函数,通过构造函数的参数选项,将需要监听的数据对象传入。然后实例化数据监听器 Observe
27、r,实现对数据的监听,实例化 Compile,解析和编译模板中的指令和数据绑定。通过 Watcher连接数据和模板,当数据有变动时通知视图更新,当界面上有用户交互操作而导致数据变化时,通知数据进行更改,从而实现 MVVM 模式的双向绑定。3 结语架构模式作为一种设计理念,本质上是对系统中的实体以及实体之间关系的抽象描述,而框架作为实现这个理念的存在,则是用来加固现有架构形成的空间,其实现手段是通过更高层次的代码封装。随着业务继续发展,软件越来越复杂是必然趋势,这也符合热力学的熵增定律。不管是架构理念还是框架技术,都是为了应对软件系统日益复杂所带来的困难而出现的。Web 前端的发展,是在不断地解
28、决问题中诞生新的技术,是社会在不断发展中催生的新技术,同时新技术又促进社会的前进,相互交织,螺旋前进!参考文献1 游俊慧.MVC、MVP、MVVM三种架构模式的对比J.办公自动化,2020,25(22):11-12+27.2 朱海萍,丁西,刘链.Web前端中基于MVVM框架的技术应用研究J.科技资讯,2020,18(30):8-10.3 李嘉,赵凯强,李长云.Web前端开发技术的演化与MVVM设计模式研究J.电脑知识与技术,2018,14(2):221-222+251.Dynamics,2017,40(2):194-196.12 AIKMEE B,PLOEN S R.Convex Progra
29、mming Approach to Powered Descent Guidance for Mars LandingJ.Journal of Guidance,Control,and Dynamics,2007,30(5):1353-1366.13 BLACKMORE L,AIKMEE B,SCHARF D P.Minimum-landing-error Powered-descent Guidance for Mars lan-ding Using Convex OptimizationJ.Journal of Gui-dance,Control,and Dynamics,2010,33(
30、4):1161-1171.14 AIKMEE B,CARSON J M,BLACKMORE L.Lossless Convexification of Nonconvex Control Bound andPointing Constraints of the Soft Landing Optimal Control Pro-blemJ.IEEE Transactions on Control Systems Technology,2013,21(6):2104-2113.15 程光辉.火箭垂直回收轨迹优化与制导技术研究D.哈尔滨:哈尔滨工业大学,2020.16 贾山,赵建华,陈金宝,等.可复用运载火箭着陆装置展开与着陆分析J.航天返回与遥感,2022,43(5):11-23.17 肖杰.重复使用运载器着陆支架展开锁定机构设计与性能分析D.南京:南京航空航天大学,2017.上接第12页