框架与库的最大区别就是代码的风格确认,库只是页面级别的选择,而架构则关注于整个程序的设计css
做为软件中的99口诀,软件设计要是没个mvc就好像不是正规军同样,前端也是这样,将html理解为view,js理解为controller,js的通信(主要指ajax)交互理解为model的获取,那么前端就是一个标准的mvc架构,其写法大体是这样的html
html/view:前端
<button class="btn btn-info" id='save'>提交</button>
js/controller:ajax
$('#save').click(function() { $.post('/api/save').done(function(res) { consoel.log(res); }).fail(function(error) { consoel.log(error); }) });
ajax就是与model的交互后端
值得注意的是浏览器是基于事件触发的,一切响应都基于事件,与咱们自定义的函数最大的区别就是其第一个参数必定为event,因此也就能够明确的代表js经过选择器进行事件的赋值,以达到控制的目的,so...做为一个前端理解为mvc的架构师,就须要对其写法进行简单的肯定,好比:api
js/controller-->更明确的controller结构浏览器
(function(){ //初始化 //将事件业务描述化 function save(event){ } $.controller.a={ '#save':{ click:save } } })()
$.controller为全部的控制器,其中的a就是改页面的controller的内容,然后在结合简单的架构封装,好比路由或者在html上增长加载选项,就可让这个js做用于当前的view,固然这种写法是用来描述的,在js加载器不断完善,已融入为架构的一部分的状况下,controller早就能够更加的对象化,好比这样:架构
define(function(require, exports, module) { //初始化参数 module.exports = { '#save':{ click:save } } //事件业务化 function save(event) { //.... } })
看着很熟悉吧,没错,用了seajs,加载器是架构的一部分,程序的设计就是api的设计(无视如何掉用的地方),单说这样的写法是否是让人感受更加的mvc呢?mvc
总之,前端的mvc大体就是将html看做view,一切与view无关的事情统统忽略(根据架构,可能会有1~2行的代码用以描述controller),将js看做controller,其经过选择器(即mvc中的接口)的方式获取view并进行操做,并经过ajax与后台(model)进行交互(M的概念一致比较弱化),以此达到解耦的目的框架
固然前端mvc包含mvc的全部缺点(依赖接口,更多的是接口太多,甚至没法固定接口),尤为在前端这种特殊的业务环境下,在其业务描述一定基于事件(这在前端确定避免不了)的前提下,类似的业务总会让人措手不及,controller的描述也就变的无比蛋疼...
解决问题的办法永远都是分层,mvvm也是同样,将基于事件的驱动,修正为基于方法,甚至基于属性,就是一个更好的方式,mvvm的控制器并不会去监听浏览器的事件,而是监听一个属性表,由浏览器的事件修改属性,以触发控制器中的方法,增长了一层控制业务的属性,而这层属性被称为vm
举个栗子:
假设一个分页的业务,在两种架构中m和v都同样,则:
define(function(require, exports, module) { //初始化参数 var page=1,totalpage=10; module.exports = { '#pre':{ click:pre }, '#next':{ click:next }, '#last':{ click:last }, '#first':{ click:first } } //事件业务化 function pre(event) { page=(page===1)?1:page-1; exec(); } function next(event){ page=(page===totalpage)?totalpage:page+1; exec(); } //...last,first //总会有大量的通用业务,好比这个 function exec(){ $.ajax('/api/users',{ page:page, }) } })
依赖于属性的变化,so...
define(function(require, exports, module) { //初始化参数 var page=1,totalpage=10; module.exports = { '#pre':{ click:pre }, '#next':{ click:next }, '#last':{ click:last }, '#first':{ click:first } } //事件业务化 function pre(event) { page=(page===1)?1:page-1; } function next(event){ page=(page===totalpage)?totalpage:page+1; } //...last,first //真正的业务,须要监控page属性 $.watch('page',function(newv,oldv){ $.ajax('/api/users',{ page:page }) }); })
无视$.watch的存在,至少咱们知道那里面包含的就是真正的业务逻辑,而所谓的事件,都只是用来修改属性的对吧,就目前来说,他跟mvc仍是很像,若是感受到mvvm中的事件都只是修改属性的特色的化,结合dom赋值的特色,在view中经过onclick属性修改属性标签的化,就可以将全部的接口(选择器)所有的干掉...换而研制,依赖vm的变化,而非事件的变化,将业务的重点至于方法中而非事件中
若是了解js,html,css分离肯能会感受到,在html中写onclik是否是太耦合了...没错,单说耦合的话的确是这样,但在前端大多数场景中,这种耦合是有必要的(尼玛都是一我的写,又不像先后端分离那样明显),这种耦合能够消灭全部的接口创建,也就是所谓了无选择器和自动执行的特色
mvc,mvp,mvvm进场在一块儿比较的三胞胎,前端彷佛不流行mvp-。-
假设mvc是基础,基于vc的强化叫mvvm,那基于vm的强化就叫mvp,model的获取是经过ajax,前端根model已没法在进行太多的封装(在整就到后台了),so...好像仍是没有解释mvp-。-
mvp大体就是充血模式吧,就酱紫
固然了,前端mvc和mvvm是各位大神根据实践一步步总结出来的,而非想像上面简单的分析出来的,这里只是架构风格和业务写法上作的简单分析,更重要的区别仍是要给予实践才能感觉到,任何架构都有适用的范围,百数内的排序仍是快排好,买名牌仍是实体店放心,万能架构仍是算了吧