最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 浅析前端MVC

    正文概述 掘金(Blend)   2020-12-26   293

    MVC是什么

    MVC是一种经典的软件架构模式,从学习Java、andriod到学习JavaScript,都遇到过它,再一次来学习它的概念:

    MVC全称Model–view–controller,将应用程序分为三个部分:Model(模型)View(视图)Controller(控制)

    • Model(模型):负责管理应用程序的数据
    • View(视图):负责对Model层中的数据进行展示
    • Controller(控制):负责用户和应用程序之间的交互

    在前端中,model层就是管理数据,实现数据的增删改查等操作,view层负责DOM等操作导致model层的数据改变后,重新渲染页面,Controller层负责连接model和view,它接受用户输入(例如鼠标单击或文本输入)并处理用户交互的回调。

    下面通过一个简陋的小的应用程序来了解MVC的具体使用:

    浅析前端MVC

    下面四个按钮对上面的数值进行加减乘除操作,再将结果显示在页面上,可以将这个程序分为MVC三个模块:

    Model:负责从localstorage数据获取和将数据更新到localstorage

    const m = {
        //从localstorage数据获取
        data: {
            result: parseInt(localStorage.getItem('data'))
        },
        //数据更新到localstorage
        update(data) {
            Object.assign(m.data, data)
            eventBus.trigger("updated")
            localStorage.setItem('data', m.data.result)
        }
    
    }
    

    View:负责将model层的数据和HTML渲染到页面

    const v = {
        //视图的元素
        el: null,
        //包裹元素的容器
        html: `
        <div>
        <div class="result">
            <span id="output">{{n}}</span>
        </div>
        <div class="button">
        <button  id="add1">+1</button>
        <button  id="min1">-1</button>
        <button  id="mul2">*2</button>
        <button  id="div2">/2</button>
        </div>
        </div>
        `,
        //初始化
        init(container) {
            v.el = $(container) //将容器保存起来
            v.render()
        },
        //渲染+更新
        render(n) {
            if (v.el.children.length !== 0) v.el.empty();
            v.el = $(v.html.replace('{{n}}', n)).appendTo($(v.el))
        },
    }
    

    Controller:负责为元素绑定事件,监听用户的点击按钮操作,通过回调函数更新model数据,再让view层渲染到页面

    const c = {
        init(container) {
            v.init(container) 
            v.render(m.data.result) //view=render(m.data.result)//视图等于渲染数据
            c.autoBindEvent()
            eventBus.on("updated", () => {
                v.render(m.data.result)
            })
        },
        v.el.on("click", "#add1", () => {
        m.update({
            result: m.data.result + 1
            })
        })
        v.el.on("click", "#min1", () => {
            m.update({
                result: m.data.result - 1
            })
        })
        v.el.on("click", "#mul2", () => {
            m.update({
                result: m.data.result * 2
            })
        })
        v.el.on("click", "#div2", () => {
            m.update({
                result: m.data.result / 2
            })
        })
    }
    

    可以观察到代码中使用了自定义的eventBus来完成Controller层和Model层之间的通信,下面就来聊一聊各模块之间的通信工具——EventBus

    EventBus

    EventBus 称为事件总线,它的核心思想是发布订阅者模式,我们可以通过调用EventBus 的接口来注册发送事件或接收事件,能达到任意模块之间的通信。

    浅析前端MVC

    初始化

    如何自定义使用eventBus呢?首先要进行初始化

    import $ from "jquery"
    const eventBus = $(window)
    

    通过JQuery,把eventBus放在全局

    触发事件

     eventBus.trigger(eventName, data)
    

    在上个MVC小程序中可以看到 ,M层进行localStorage的数据更新操作后就会触发事件名为updated的事件,EventBus就会传达给监听这个事件的模块,进行通信。

    监听事件

     eventBus.on(eventName, () => {
                //操作
            })
    

    在C层监听到事件名为updated的事件发生后就会触发回调函数,通知V层渲染更新M层的新数据。

    取消监听

     eventBus.off(eventName, () => {
                //操作
            })
    

    也可以通过off这个API来取消监听

    表驱动编程

    表驱动方法编程(Table-Driven Methods)是一种编程模式,简单讲是指用查表的方法获取值。适用场景:消除代码中频繁的if else或switch case的逻辑结构代码,使代码更加直白.

    现在通过利用表驱动方法来优化MVC小程序C层中的绑定事件代码:

    const c = {
       ……
        events: {
            "click #add1": "add",
            "click #min1": "min",
            "click #mul2": "mul",
            "click #div2": "div"
        },
        add() {
            m.update({
                result: m.data.result + 1
            })
        },
        min() {
            m.update({
                result: m.data.result - 1
            })
        },
        mul() {
            m.update({
                result: m.data.result * 2
            })
        },
        div() {
            m.update({
                result: m.data.result / 2
            })
        },
        autoBindEvent() {
            for (let key in c.events) {
                const space = key.indexOf(" ")
                const part1 = key.slice(0, space)
                const part2 = key.slice(space + 1)
                const value = c[c.events[key]]
                console.log(value);
                v.el.on(part1, part2, value);
            }
        },
    
    

    对比之前的代码,表驱动方法编程的优势便体现出来了:

    1、可读性更强,自动绑定事件,一目了然。

    2、更容易修改,要增加新的绑定事件,只要修改数据即可,不需要修改流程。

    3、重用,第一种方法的只有绑定的事件名称、监听元素和回调函数不一样,逻辑都是一样的,产生了很多重复的代码。表驱动方法编程将这种相同的逻辑提取出来,而把容易发生变化的部分提到外面。

    模块化

    通过构造一个简单的MVC模式的小应用让我学习了模块的封装。上例MVC小程序中的我们已经将程序划分为三个对象并完成了模块的封装,只需把C层对象导出,其他页面引入C对象,通过我们在暴露的init方法初始化传给C对象一个容器,就可以添加使用这个计算小程序,而不需要知道其内部的具体实现。

    目前最常使用的两种模块化规范就是 ESM (ES Module)和CommonJS

    ESM (ES Module)

    语法规则

    import defaultExport from "module-name";
    import * as name from "module-name";
    import { export1 , export2 } from "module-name";
    import { export1 , export2 as alias2 , [...] } from "module-name";
    import defaultExport, { export1 [ , [...] ] } from "module-name";
    // 等 ...
    
    export let name1, name2, …, nameN; // also var, const
    export { name1, name2, …, nameN };
    export default function (…) { … } // also class, function*
    export { name1, name2, …, nameN } from …;
    // 等 ...
    

    CommonJS

    语法规则

    'use strict';
    
    var lodash = require('lodash');
    
    const result = lodash.every(
      [true, 1, null, 'yes'],
      Boolean,
    );
    
    module.exports = result;
    

    相比 esm 主要差别在语法上:

    • esm
      • import a from 'b'
      • export default c
    • cjs
      • const a = require('b')
      • module.exports = c

    起源地下载网 » 浅析前端MVC

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元