框架与库的最大区别就是代码的风格确认,库只是页面级别的选择,而架构则关注于整个程序的设计

MVC

  作为软件中的99口诀,软件设计要是没个mvc就好像不是正规军一样,前端也是这样,将html理解为view,js理解为controller,js的通讯(主要指ajax)交互理解为model的获取,那么前端就是一个标准的mvc架构,其写法大致是这样的

html/view:

 <button class="btn btn-info" id='save'>提交</button>

js/controller:

    $('#save').click(function() {
        $.post('/api/save').done(function(res) {
            consoel.log(res);
        }).fail(function(error) {
            consoel.log(error);
        })
    });

ajax就是与model的交互

值得注意的是浏览器是基于事件触发的,一切响应都基于事件,与我们自定义的函数最大的区别就是其第一个参数一定为event,所以也就可以明确的表明js通过选择器进行事件的赋值,以达到控制的目的,so...作为一个前端理解为mvc的架构师,就需要对其写法进行简单的确定,比如:

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大致就是将html看作view,一切与view无关的事情通通忽略(根据架构,可能会有1~2行的代码用以描述controller),将js看作controller,其通过选择器(即mvc中的接口)的方式获取view并进行操作,并通过ajax与后台(model)进行交互(M的概念一致比较弱化),以此达到解耦的目的

当然前端mvc包含mvc的所有缺点(依赖接口,更多的是接口太多,甚至无法固定接口),尤其在前端这种特殊的业务环境下,在其业务描述必定基于事件(这在前端肯定避免不了)的前提下,相似的业务总会让人措手不及,controller的描述也就变的无比蛋疼...

mvvm

  解决问题的办法永远都是分层,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是不是太耦合了...没错,单说耦合的话的确是这样,但在前端大多数场景中,这种耦合是有必要的(尼玛都是一个人写,又不像前后端分离那样明显),这种耦合可以消灭所有的接口建立,也就是所谓了无选择器和自动执行的特点

mvp

mvc,mvp,mvvm进场在一起比较的三胞胎,前端似乎不流行mvp-。-

假设mvc是基础,基于vc的强化叫mvvm,那基于vm的强化就叫mvp,model的获取是通过ajax,前端根model已无法在进行太多的封装(在整就到后台了),so...好像还是没有解释mvp-。-

mvp大致就是充血模式吧,就酱紫

  当然了,前端mvc和mvvm是各位大神根据实践一步步总结出来的,而非想像上面简单的分析出来的,这里只是架构风格和业务写法上做的简单分析,更重要的区别还是要给予实践才能感受到,任何架构都有适用的范围,百数内的排序还是快排好,买名牌还是实体店放心,万能架构还是算了吧

 

posted on 2015-11-08 17:10  Glimis  阅读(6344)  评论(0编辑  收藏  举报