一、MVC 是什么

1.基本介绍

MVC这个设计模式认为每个模块都可以写成三个对象,分别是 M、V、C

  • M - Model(数据模型)负责操作所有数据
  • V - View(视图)负责所有 UI 界面
  • C - Controller(控制器)负责其他(比如负责监听用户事件,然后调用 M 和 V 更新数据和视图;来处理各种逻辑和数据转化)

    2.示例说明

  • Model示例:

    1. const eventBus = $(window) // 全局变量eventBus;用于对象间的通信
    2. const m = {
    3. data: {// 数据源},
    4. create() {// 增数据},
    5. delete() {// 删数据},
    6. update(data) { // 更新数据
    7. Object.assign(m.data, data) // data里的数据赋值到 m.data.n
    8. eventBus.trigger('m:updated') // 触发事件
    9. localStorage.setItem('n', m.data.n) // 存储数据
    10. },
    11. get() {// 获取数据}
    12. }
  • View示例:

    1. const v = {
    2. el: null, // 容器
    3. html: ` `, // 渲染 html
    4. init(container) {
    5. v.el = $(container) // v.el变成用jquery封装的对象
    6. },
    7. render() {} // 新增或重新渲染
    8. }
  • Controller示例:

    1. const c = {
    2. // 初始化并且绑定事件
    3. init(container) {
    4. v.init(container)
    5. v.render(m.data) // view = render(data);第一次渲染
    6. c.autoBindEvents()
    7. eventBus.on('m:updated', () => {
    8. v.render(m.data)
    9. }) // 监听到m里数据更新时触发render
    10. },
    11. events: {// 事件(哈希表形式存储)},
    12. autoBindEvents() {
    13. for (let key in c.events) { }
    14. }
    15. } // 遍历c.events,自动绑定事件

    二、关于 EventBus

    1.基本作用:

  • EventBus主要用于对象间通信

  • 使用EventBus可以满足最小知识原则,m 和 v 互相不知道对方的细节,但是却可以调用对方的功能

    2.EventBus的一些API

    EventBus提供了on(监听事件)、off(移除一个事件处理函数)和trigger(触发事件)等API ```javascript eventBus.trigger(‘m:updated’)

eventBus.on(‘m:updated’, () => { v.render(m.data) })

  1. - [x] `trigger`触发`m`里的`updated`之后,`on`事件监听到之后执行`v.render`;从而实现模块间的通信
  2. <a name="lOIdn"></a>
  3. # 三、表驱动编程
  4. <a name="53a0x"></a>
  5. ## 1.基本的定义与作用
  6. - 这里的表指的是**哈希表**;简单的理解为**用哈希表来整理重复代码**
  7. - **作用:**可以减少重复代码,只将**重要的信息**放在表里,然后利用表来编程
  8. <a name="DRI4c"></a>
  9. ## 2.示例:
  10. <a name="ei1Ay"></a>
  11. #### 原本有四个事件,我们需要去绑定这四个事件;原始的写法:
  12. ```javascript
  13. // 首先需要获取到这四个事件
  14. const $button1 = $('#add1')
  15. const $button2 = $('#minus1')
  16. const $button3 = $('#multiply2')
  17. const $button4 = $('#divide2')
  18. //然后再一个个的绑定事件
  19. $button1.on("click",() => {
  20. let n = parseInt($number.text())
  21. n += 1
  22. localStorage.setItem('n', n) // 存储数据,页面刷新之前的数据也还在
  23. $number.text(n)
  24. })
  25. $button2.on("click",() => {
  26. let n = parseInt($number.text())
  27. n -= 1
  28. localStorage.setItem('n', n)
  29. $number.text(n)
  30. })
  31. $button3.on("click",() => {
  32. let n = parseInt($number.text())
  33. n *= 2
  34. localStorage.setItem('n', n)
  35. $number.text(n)
  36. })
  37. $button4.on("click",() => {
  38. let n = parseInt($number.text())
  39. n /= 2
  40. localStorage.setItem('n', n)
  41. $number.text(n)
  42. })
  • 可以看到永远都是在做重复的事情,只有部分区别
  • [x] 并且随着事件数的增加,所需要增加的代码也变多了

    使用表驱动编程之后的写法:

    1. // 重要的数据提取出来写成哈希表的形式
    2. events: {
    3. 'click #add1': 'add',
    4. 'click #minus1': 'minus',
    5. 'click #multiply2': 'mul',
    6. 'click #divide2': 'div'
    7. },
    8. add() {
    9. m.update({n: m.data.n + 1})
    10. },
    11. minus() {
    12. m.update({n: m.data.n - 1})
    13. },
    14. mul() {
    15. m.update({n: m.data.n * 2})
    16. },
    17. div() {
    18. m.update({n: m.data.n / 2})
    19. },
    20. // 自动绑定事件
    21. autoBindEvents() {
    22. for (let key in c.events) {
    23. const value = c[c.events[key]]
    24. const spaceIndex = key.indexOf(' ') // 得到索引
    25. const part1 = key.slice(0, spaceIndex)
    26. const part2 = key.slice(spaceIndex + 1) // 分成两个字符串
    27. v.el.on(part1, part2, value)
    28. }
    29. }
  • [x] 但是可以看到,第一种基本都是在做重复性动作,而第二种却基本没有什么重复的地方

  • [x] 随着事件数的增加,只需要在表中加一行,并且只需要关键词即可

    四、个人对于模块化的理解

    模块化简单的理解为:

    将一个整体分离成一个个小的模块;同时各个模块留出一些接口来供他人使用

    用比较专业的话来讲:

    将JavaScript程序拆分为可按需导入的单独模块的机制

    使用模块化的优点:

  • [x] 避免了全局变量的污染

  • 降低了耦合度,方便多人合作,互不干扰
  • 提高代码复用
  • 模块化写代码,使得代码逻辑更清晰
  • 降低维护难度

    注:尽量不要用JS来写CSS的代码(样式与行为分离思想)

    比如:不要在JS使用.show().hide().css()来显示隐藏或改写CSS
    而应该使用.addClass().removeClass()等来给css添加或移除class,css自己控制有无这个class时的样式