浅析 MVC

MVC 三个对象分别做什么?

MVC是一种设计模式,所有的页面都可以使用 MVC来优化代码结构,MVC包括三类对象,将他们分离以提高灵活性和复用性。

模型model:用于封装与应用程序的业务逻辑相关的数据以及对数据的处理方法,会有一个或多个视图监听此模型。一旦模型的数据发生变化,模型将通知有关的视图。

视图view:是在屏幕上的表示,描绘的是model的当前状态。当模型的数据发生变化,视图相应地得到刷新自己的机会。

控制器controller:定义用户界面对用户输入的响应方式,起到不同层面间的组织作用,用于控制应用程序的流程,它处理用户的行为和数据model上的改变。

伪代码

const m ={
  data:数据
  update(){
  数据的更新
  }
}
const v = {
   html:页面加载
   init() {初始化数据}
   render(){
   数据发生变化后刷新视图
   }
}

const c = {
绑定事件,响应用户操作
}

复制代码

代码

import $ from 'jquery'

const eventBus = $(window)
// 数据相关都放到m
const m = {
  data: {
    n: parseInt(localStorage.getItem('n'))
  },
  create() {},
  delete() {},
  update(data) {
    Object.assign(m.data, data)
    eventBus.trigger('m:updated')
    localStorage.setItem('n', m.data.n)
  },
  get() {}
}
// 视图相关都放到v
const v = {
  el: null,
  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>
`,
  init(container) {
    v.el = $(container)
  },
  render(n) {
    if (v.el.children.length !== 0) v.el.empty()
    $(v.html.replace('{{n}}', n))
      .appendTo(v.el)
  }
}
// 其他都放在c
const c = {
  init(container) {
    v.init(container)
    v.render(m.data.n) // view = render(data)
    c.autoBindEvents()
    eventBus.on('m:updated', () => {
      v.render(m.data.n)
    })
  },
  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)
    }
  }
}

复制代码

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

EventBus 主要用于对象间的通信,EventBus基本的API有on(监听事件),trigger(触发事件), off(取消监听)方法。

//伪代码
eventBus.trigger('xxx') //触发事件xxx
eventBus.on('xxx', function())  //监听到xxx 执行function()
eventBus.off('xxx')  //取消监听xxx
复制代码

表驱动编程是做什么的?

所谓表驱动法(Table-Driven Approach),是指用直接查表的方法获取值,而不通过(if else) 逻辑判断,实现逻辑和数据的分离。事实上,凡是能通过逻辑语句来选择的事物,都可以通过查表来选择。对简单的情况而言,使用逻辑语句更为容易和直白。但随着逻辑链的越来越复杂,查表法也就愈发显得更具吸引力。

//代码示例如下
bindEvents(){
  const pause = () => {}
  const play = () => {}
  const slow = () => {}
  const normal = () => {}
  const fast = () => {}
  document.querySelector('#btnPause').onclick = pause
  document.querySelector('#btnPlay').onclick = play
  document.querySelector('#btnSlow').onclick = slow
  document.querySelector('#btnNormal').onclick = normal
  document.querySelector('#btnFast').onclick = fast
}

// 用表驱动法简化代码,易于扩展和重用,只需更改表数据即可
  events:{
    '#btnPause':'pause',
    '#btnPlay':'play',
    '#btnSlow':'slow',
    '#btnNormal':'normal',
    '#btnFast':'fast'
  },
  bindEvents: () => {
    for(let key in player.events){
      if(player.events.hasOwnProperty(key)){
        document.querySelector(key).onclick = player[player.events[key]]
      }
    }
  }
复制代码

如何理解模块化?

模块化就是把功能较多的整体划分成多个更细小的功能模块,每个模块间都是独立的,相互不影响,这样的代码维护起来更方便,不需要知道整体怎样,只需要知道这个模块的知识即可,复用性也更强。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享