谈谈我对刚学习的 MVC 的理解

289 阅读2分钟

1. MVC 三个对象是什么?分别做什么?

  • M:即 Model(数据模型),负责操作所有数据 有以下伪代码为示例:
const m = {
    data:{数据源},
    create(){增},
    delete(){删},
    update(data){
        Object.assign(m.data, data) // 新数据替换旧数据
        eventBus.trigger('m:update') // eventBus触发'm:update'信息,通知 View 刷新页面
    },
    get(){查}
}
  • V: 即 View(视图),负责所有的 UI 界面 有以下伪代码为示例:
const v = {
    el: null, // 要重新渲染的元素
    html:` 显示内容的代码`,
    init(container){
        v.el = $(container)
    },
    render(){
        重新渲染内容
    }
}
  • C: 即 Controller(控制器),负责除了 M 和 V 以外的其他事情 有以下伪代码为示例:
const c = {
    v.init(container){ 
       // 初始化 View
       // view = render(data)
    v.render(m.data.n) // 第一次渲染
    c.autoBindEvents() // 自动事件绑定
    eventBus.on('m:updated',()=>{
          // eventBus 触发'm:update' ,View 重新渲染,如
          // v.render(m.data.n)
        })
    },
    events:{
        // 哈希表记录
        // 如
        // 'click #add1': 'add',
        // 'click #minus1': 'minus',
    },
    add(){
        // 如
        // m.update({n: m.data.n + 1})
    },
    minus(){
        // 如 
        //  m.update({n: m.data.n - 1})
    },
    autoBindEvents(){
        // 自动绑定事件,如
        // for(let key in c.events) {
        //     const value = c[c.events[key]]
        //     const spaceIndex = key.indexOf(' ')
        //     const part1  = key.slice(0, spaceIndex)
        //     const part2 = key.slice(spaceIndex + 1)
        //     v.el.on(part1, part2, value)
        // }
    }
}

2. EventBus 有哪些 API,是做什么用的?

  • EventBus 基本的 API 有 on(监听事件),trigger(触发事件),off(取消监听)方法。
  • 用于模块间的通讯,view 组件层面,父子组件、兄弟组件通信都可以 EventBus 处理
//EventBus.js
class EventBus{
    constructor(){
        this._eventBus =$(window)
    }
    on(eventName, fn){
        return this._eventBus.on(eventName,fn)
    }
    trigger(eventName,data){
        return this._trigger.tiggger(eventName,data)
    }
    off(eventName, fn){
        return this._eventBus.off(eventName,fn)
    }
}
export default EventBus

//new.js
import EventBus from 'EventBus.js'
const e =new EventBus()
e.on()
e.trigger()
e.off()

3. 什么是表驱动编程?

  • 表驱动法是一种编程模式,从表(哈希表)里面查找信息而不是使用逻辑语句(if…else…switch,可以减少重复代码,只将重要的信息放在表里,然后利用表来编程,与逻辑语句相比较有着更稳定的复杂度。
  • 以下代码就有着相似度很高的问题
bindEvents(){
    v.el.on('click','#add1',()=>{
        m.data.n +=1
        v.render(m.data.n)
    })
    v.el.on('click','#minus1',()=>{
        m.data.n-=1
        v.render(m.data.n)
    })
    v.el.on('click','#mul2',()=>{
        m.data.n*=2
        v.render(m.data.n)
    })
    v.el.on('click','#divide2',()=>{
        m.data.n/=2
        v.render(m.data.n)
    })
}

  • 用表驱动编程后,将代码不重复的部分提取到哈希表,代码简洁许多
events:{
    'click #aa1':'add',
    'click #minus1':'minus',
    'click #mul2':'mul',
    'click #divide2':'div'
},
add(){
    m.update( data: {n:m.data.n +1})
},
minus(){
    m.update( data:{n:m.data.n -1})
},
mul(){
    m.update( data: {n:m.data.n *2})
},
div(){
    m.update(data: {n:m.data.n /2})
}

4. 我是如何理解模块化的

  • 我个人理解的模块化,用最简单的话来说就是:块的内部数据与实现是私有的, 只是向外部暴露一些接口(方法)与外部其它模块通信,这可以让每个模块都独立出来。如果某个模块出了问题就不会影响别的模块,所以在模块化编程的时候可以不用太过于关注当前模块对其他模块的影响。

模块化的好处

  1. 避免变量污染,命名冲突
  2. 提高代码复用率
  3. 提高维护性
  4. 依赖关系的管理