浅析MVC

46 阅读3分钟

什么是MVC

  • MVC就是一种设计模式,用于简化我们的代码,方便管理,是万金油,几乎什么代码都能用MVC重构

MVC三个对象

  • M:Model,模型model用于封装与应用程序的业务逻辑相关的数据以及对数据的处理方法,会有一个或多个视图监听此模型。一旦模型的数据发生变化,模型将通知有关的视图。主要就是用来存放数据部分。
代码示例://数据相关 放到m
const m = { data: {
n: parseInt(localStorage.getItem('n')) } }
  • V:View,视图view是它在屏幕上的表示,描绘的是model的当前状态。当模型的数据发生变化,视图相应地得到刷新自己的机会。
代码示例:// 视图相关都放到v
    const v = {
    html: ` <div >
<div class="output">
    <span id="number">{{n}}</span>
</div>
<div class="actions">
    <button id="add1">+1</button>
    <button id="minus1">-1</button>
    <button id="mul2">*2</button>
    <button id="divide2"2</button>
</div>
</div>`
  • C:Controler,控制器controller定义用户界面对用户输入的响应方式,起到不同层面间的组织作用,用于控制应用程序的流程,它处理用户的行为和数据model上的改变。也就是存放除了数据和视图以外代码的地方。
代码示例://其他放到c
 const c = {
 init(container) {//得到html内容 然后初始化
  }
}
  • MVC中V和C经常无法分离,所以后来会将V和C合并成View。

EventBus

  • EventBus主要用于各个对象之间的通信
  • EventBus主要有三个API
  • on 用于监听对象
  • trigger用于触发事件
  • off用于取消对象监听
  • 当我们想让M的数据更新后,V视图也能跟着改变的时候,就可以用到EventsBus
代码示例:const eventBus = $(window) //获取EventBus对象
const m = {
  data: {
    ...
  },
  update(data) {
    // trigger 触发事件更新数据
    eventBus.trigger('m:updated')
  }
}

const v = {
  render(data) {
    ...更新数据
  }
} 

const c={ 
 eventBus.on('m:updated', () => {  // on方法执行监听后触发 v 视图渲染
      console.log('here')
      v.render(m.data.n)
    })

表驱动编程是做什么的

  • 表驱动编程的意义在于逻辑与数据的分离。( 类似于事件委托
  • 主要在于把重复的代码省去,让需要变化的代码留下
  • 例如下面这个代码,v.render()执行了多次
    bindEvents() {
        //绑定鼠标事件,绑定在最外面(#app1)上面,监听祖父元素,事件委托
        v.container.on('click', '#add1', () => {
            m.data.n += 1
            v.render()
        })
        v.container.on('click', '#minus1', () => {
            m.data.n -= 1
            v.render()
        });
        v.container.on('click', '#mul2', () => {
            m.data.n *= 2
            v.render()
        });
        v.container.on('click', '#divide2', () => {
            m.data.n /= 2
            v.render()
        });

    }
  • 这样的代码可以用表驱动编程改写成如下形式
 events: {                   //events表,把事件写进来
    'click #add1': 'add',
    'click #minus1': 'minus',
    'click #mul2': 'mul',
    'click #divide2': 'div',
  },
  add() {
    m.update({n: m.data.n + 1})
  },
  minus() {
    m.update({n: m.data.n - 1})
  },
  mul() {
    m.update({n: m.data.n * 2})
  },
  div() {
    m.update({n: m.data.n / 2})
  },
  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)   
    }
  }
}
  • 这样做的好处就是减少了代码重复,并且逻辑更清晰,不需要依赖DOM,同时增加了可扩展性。

我是如何理解模块化的

  • 我认为模块化就是让两个模块之间互不干扰,用export导出和import导入,好处是在A模块里的数据完全不用关心在B里面的数据。且可以让一些模块作为中间层,如果要改变的时候只需要改变中间层。