前端mvc與mvvm


  框架與庫的最大區別就是代碼的風格確認,庫只是頁面級別的選擇,而架構則關注於整個程序的設計

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是各位大神根據實踐一步步總結出來的,而非想像上面簡單的分析出來的,這里只是架構風格和業務寫法上做的簡單分析,更重要的區別還是要給予實踐才能感受到,任何架構都有適用的范圍,百數內的排序還是快排好,買名牌還是實體店放心,萬能架構還是算了吧

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM