模組化與MVC的VC

littlebirdflying發表於2018-04-16

1. 模組化

模組化是 MVC 的前提。
MVC 可以解決一個很重要的問題,就是寫完程式碼就忘的問題,通過對檔案的命名和程式碼的簡化,可以更加方便的辨別程式碼的功能與作用。
以js程式碼為例,我們把main.js,按照功能拆分成module-1.js等三個檔案(名字根據做的事情不同而不同),形成模組。這樣每個檔案的程式碼都會小而清晰,這也就是模組化的一種體現。

<!--index.html-->
<body>
    module-1 of html
    module-2 of html
    module-3 of html
    <scirpt src="module-1.js"></script>   
    <scirpt src="module-2.js"></script>   
    <scirpt src="module-3.js"></script>  
</body>
複製程式碼

2. 如何使用立即執行函式

不同模組程式碼裡,相同的全域性變數會造成程式碼衝突,所以我們需要把全域性變數變成區域性變數——立即執行函式的使用。
程式碼格式如下:

!function(){
    your code
}.call()
複製程式碼

2.1 思路步驟 (這個試錯過程還是很重要的)

1.我們不想要全域性變數
2.我們要使用區域性變數
3.ES 5 裡面,只有函式有區域性變數
4.於是我們宣告一個 function xxx , 然後xxx.call()
5.這個時候 xxx是全域性變數(全域性函式)
6.所以我們不能給這個函式名字
7.function(){}.call()
8.但是 Chorme 報錯, 語法錯誤(chorme sb)
9.試出來一種方法可以不報錯: 
    (1)  !function(){}.call()   (我們不在乎這個匿名函式的返回值,所以加個 ! 取反沒關係)
    (2)(function(){}).call()         不推薦(xxx 換行 (前面的東西) 這樣就亂了)
    (3) frank81937501975.call()    不推薦   (利用隨機數避免重複衝突)
複製程式碼

通過使用立即執行函式,我們實現了程式碼之間真正的模組化(這屬於js的bug,我們必須用這種方式進行程式碼隔離)。

2.2 程式碼模組隔離之後如何進行通訊呢?利用閉包

1.可以藉助全域性物件 window 進行賦值取值操作即可。
2.還可以利用閉包。

// module-1
!function(){}.call()
!function(){
    //  code of module-1
    var person = {
        name: 'frank',
        age: 18
    }
    window.frankGrowUp = function() {
        person.age += 1    // 函式用了它以外的變數 person,所以fn和person就是閉包 ,閉包用來對資料隱藏細節,還可以進行訪問控制
        return person.age
    }
}.call()

// module-2
!function(){
    // code of module-2
    var newAge = window.frankGrowUp()
    console.log(newAge)  // 19
}.call()
複製程式碼
  1. 立即執行函式使得 person 無法被外部訪問
  2. 閉包使得匿名函式可以操作 person
  3. window.frankGrowUp 儲存了匿名函式的地址
  4. 任何地方都可以使用 window.frankGrowUp操作 person
    => 任何地方都可以使用 window.frankGrowUp操作 person,但是不能直接訪問 person

3. 用MVC中的 VC 寫程式碼

MVC Model(模型) View(檢視) Controller(控制)

<!--index.html-->
<body>
    <div id="view-1"></div>
    <div id="view-2"></div>
    <div id="view-3"></div>
    <scirpt src="module-1.js"></script>   
    <scirpt src="module-2.js"></script>   
    <scirpt src="module-3.js"></script>  
</body>
複製程式碼
// module-1.js 模組 1
!function(){
    var view = 找到對應的模組1元素 
    var controller = {
        view: null,
        init: function(view) {
            this.view = view // 給controller.view 賦值
            this.操作1()    // 這裡的 this是通過 controller 物件呼叫決定的(最下面)
            this.操作2()
        },
        操作1:function(){},
        操作2:function(){},
    }
    controller.init(view)    // 執行操作
}.call()
複製程式碼

下面這兩個模組用來舉例子,略亂

// module-2.js 模組 2
!function(){
    var view = document.querySelector('#view-2')  
    var controller = {
        view: null,
        init: function(view) {
            this.view = view 
            this.bindEvents()           // this.bindEvents.call(this)
        },
        bindEvents: function(){
            var view = this.view
            window.addEventListener('scroll',(x) => {
                this           // 通過箭頭函式讓函式內外this不變, this相當於一個變數
                                 // 如果是f(){}則this是使用者觸發的元素,可通過bind()繫結this
            }
        },
        active:function(){
            this.view.classList.add('xxx')
        },
        deactive: function(){
            this.view.classList.remove('yyy')
        }
    }
    controller.init(view)         // controller.init.call(controller, view)
}.call()

// module-3.js 模組 3
!function(){
    var view = 找到對應的模組3元素 
    var controller = {
        view: null,
        swiper: null,
        swiperOptions: {
            選項1:xxx,
            選項2: xxx,
            ……
        }
        init: function(view) {
            this.view = view 
            this.initSwiper()
        },
        initSwiper:function(){
            this.swiper = new Swiper(
                this.view.querySelector('選擇器'),
                this.swiperOptions
            )
        }
    }
    controller.init(view)    
}.call()
複製程式碼

這樣可以保證三個模組的程式碼結構相同,我們寫程式碼,html就放在view部分,js操作就放在controller部分
相關程式碼:MVC模式寫程式碼

4. 總結

模組化是 MVC 的前提。
利用立即執行函式隔離各個模組,但又能實現和控制不同模組之間的通訊。
利用MVC中的VC思想,保證各個模組的程式碼結構的一致性。

相關文章