您的位置:首页 > Web前端 > JavaScript

MV*(MVC、MVP、MVVM) 与 *MD(CommonJS、AMD、CMD、UMD)

2016-02-27 22:09 567 查看
参考:http://blog.csdn.net/kevin_1025745654/article/details/45815109

MV*

已知:M(数据与数据逻辑,例如ajax、本地存储模块)

后端的MVC:M提供数据API;V 即模板,可以直接从M获取数据,C 即控制显示哪个模板

前端的MV*

MVC : V(视图逻辑,backbone里的V即View模块),C(控制视图的显示,backbone里的C即Router模块)

MVP : P(Presenter主持人,或者Passive View被动视图。负责响应V,调用M,更新V)。也可以把backbone的View理解为P。

MVP与MVC的差别:MVC里的V直接调用M的接口,MVP中则不能,得通过中间人P。

MVVM : V(模板),VM(视图模型,即数据与视图绑定,数据逻辑与视图逻辑绑定。普通的M的对外提供接口,VM则自动绑定视图。angularJS里VM即controller组件,里面的逻辑即数据逻辑,里面的scope即数据)

MVVM与MVP的差别:P要显式操作V,而VM与V双向绑定。

MV*的区别在于V与M之间的流程,MVC中V直接调用M。MVP中V调用P,P再调用M。MVVM中V绑定VM,VM调用M。

*MD
模块化系统所必须的能力:

1. 定义封装的模块。

2. 定义新模块对其他模块的依赖。

3. 可对其他模块的引入支持。

CommonJS ( wiki.commonjs.org/wiki/Modules, 服务器端的模块规范),例:nodejs,browserify进行打包

AMD (Asynchronous Module Definition ,异步模块定义),例:require.js,r.js进行打包

CMD (Common Module Definition,通用模块定义),例:sea.js,grunt-cmd-transport 进行打包

ES6 模块,webpack进行打包

CommonJS 模块无需包装。CMD相比AMD更接近CommonJS Modules。CMD 推崇依赖就近,即使用时引入。AMD 推崇依赖前置,即在定义模块处引入。

对比:浏览器是否直接支持(是否必须经过打包)、是否需要包裹、是否方便引用npm上的包、代码拆分方案(首屏打包,按需加载)

UMD (Universal Module Definition,万能模块定义),一个兼容各种模块规范的模块定义写法。

单页应用
单页应用的路由模块的实现原理:

1、地址栏有锚值(有 # 号),刷新时浏览器发的请求不带 # 号及后面部分

2、通过location.hash 可以读写锚值(带#号)

3、改变锚值时会增加一条历史记录,但不会重载页面

4、window.onhashchange 监听锚值变化事件
5、另有history.pushState(状态对象, 新标题, 新url)方法和 window.onpopstate 事件。state与hash是两码事,pushState或回退的时候会触发onpopstate并传入状态对象

backbone自带路由模块,不能嵌套

angularjs 路由模块:https://github.com/angular-ui/ui-router ,可嵌套

reactjs路由模块:https://github.com/reactjs/react-router,可嵌套

组成部分:MV*、模块加载工具、路由、打包工具、UI组件

前端架构

1、无模块加载系统:html 引入一个js,js为一个自调用函数(闭包)

2、有模块加载系统:html 引入模块加载库 和 入口模块,入口模块中再去加载其他模块。这些模块可以是backbone的View、Angular的controller、React的component,也可以是完全自定义的闭包揭示模块、构造器模块

3、单页应用:在2的基础上监听 state 或 hash,重新渲染页面。

版本缓存管理

1、index 动态生成,CSS合并后在index中引入,引用路径加上 ?版本号。 在CSS 中 更改 字体文件版本号。以解决 CSS、字体文件版本问题。

2、在模块加载工具里配置版本号,来解决JS 版本问题。例如

seajs.config({

'map': [

[/^(.*)\.js$/i, '$1\.js?333']

           ]  

});

3、将 HTML 打包成 JS模块(例如grunt-common-html2js、grunt-cmd-transport),被JS require,以解决HTML版本问题。

4、require.js 利用 text.js 插件下载HTML片段

       require.config({

 paths:{

  "text":"lib/text"

 }

})

require(['jquery','text!template.html'],function($,template){

      $(".class").html(template);

})

*MD对比
浏览器是否直接支持(即是否需要经过打包)、是否需要包裹、是否方便引用npm上的包

数据绑定
本质上是三种方式 1、(angularjs 1.x)监控数据变化,操作DOM;2、(react)整体更新虚拟DOM,diff,操作DOM;3、(vue)监控数据变化,局部更新虚拟DOM,diff,操作DOM
监控数据变化之脏检查
     angularJS 1.x采用,在controller或$apply中改变scope的属性,会自动调用$dist,进行脏检查。发生变化的属性,调用其$watcher。view中写ng-,会自动为其创建$watcher。
监控数据变化之对象监控

Object.observe:Chrome、ES7;Object.observe(model,function(changes){ // changes里包含变化信息}),支持的浏览器少

监控数据变化之属性访问器
1、Object.defineProperty:Vue采用,原生支持

Object.defineProperty(obj,‘name’,//三个参数分别为:对象、属性名、属性描述对象



    configurable: false,  //属性是否可配置

    enumerable: true,    //属性是否可枚举

    writable: true,      //属性是否可重写,不能与set/get同存

    value: null,         //属性的默认值,不能与set/get同存

    set: undefined,     // 重写器,这里可以写入数据绑定逻辑

    get: undefined      // 读取器

})

Object.getOwnPropertyDescriptor(obj, 'name');// 获取属性描述对象

2、非原生:backbone的model,属性只能通过get 和 set访问,通过listen给他们挂钩子。backbone只给了监控数据变化的方法,不会自动操作DOM,隐藏没有数据绑定



MVVM对比
   1、如何检查model变化:脏检查(angularjs) 、 访问器(vue、backbone)、整体重新渲染,无需检查(react)

   2、如何更新视图:串行直接操作DOM(angularjs)、通过虚拟DOM

   3、数据绑定:单项(react)还是双向(angularJS、Vue)

   4、代码分离:JS、HTML是否分离,JSX需要经过编译,不好调试和定位错误

   5、体积、社区、文档等

   6、组件
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: