美文网首页我爱编程
模块化与MVC的VC

模块化与MVC的VC

作者: 王童孟 | 来源:发表于2018-04-16 08:57 被阅读0次

    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思想,保证各个模块的代码结构的一致性。

    相关文章

      网友评论

        本文标题:模块化与MVC的VC

        本文链接:https://www.haomeiwen.com/subject/fsdskftx.html