M

Model(数据模型),负责操作所有数据

  1. const m = {
  2. data: {
  3. n: parseInt(localStorage.getItem('n'))
  4. },//获取数据
  5. create() {},//增
  6. delete() {},//删
  7. update(data) {
  8. Object.assign(m.data, data)
  9. eventBus.trigger('m:updated')
  10. localStorage.setItem('n', m.data.n)
  11. },//改
  12. get() {}
  13. }//查
  14. }

V

View(视图),负责所有UI界面

  1. const v = {
  2. el: null,//接受一个容器
  3. html: `//生成HTML
  4. <div>
  5. <div class="output">
  6. <span id="number">{{n}}</span>
  7. </div>
  8. <div class="actions">
  9. <button id="add1">+1</button>
  10. <button id="minus1">-1</button>
  11. <button id="mul2">*2</button>
  12. <button id="divide2"2</button>
  13. </div>
  14. </div>
  15. `,
  16. init(container) {
  17. v.el = $(container)
  18. },//初始化容器
  19. render(n) {
  20. if (v.el.children.length !== 0) v.el.empty()
  21. $(v.html.replace('{{n}}', n))
  22. .appendTo(v.el)
  23. }//通过if else判断容器的后代是否存在进行增删,最后渲染到页面
  24. }

C

Controller(控制) 负责其他

  1. const c = {
  2. //初始化容器
  3. init(container) {
  4. v.init(container)
  5. v.render(m.data.n) // view = render(data)
  6. c.autoBindEvents()//自动绑定事件
  7. eventBus.on('m:updated', () => {
  8. console.log('here')
  9. v.render(m.data.n)
  10. })//监听数据的变化,重新渲染到页面
  11. },
  12. //事件太多,通过哈希表来一一列出,也正是我们所说的表驱动编程
  13. events: {
  14. 'click #add1': 'add',
  15. 'click #minus1': 'minus',
  16. 'click #mul2': 'mul',
  17. 'click #divide2': 'div',
  18. },
  19. //每个事件点击对应着数据变化的操作函数
  20. add() {
  21. m.update({n: m.data.n + 1})
  22. },
  23. minus() {
  24. m.update({n: m.data.n - 1})
  25. },
  26. mul() {
  27. m.update({n: m.data.n * 2})
  28. },
  29. div() {
  30. m.update({n: m.data.n / 2})
  31. },
  32. autoBindEvents() {
  33. for (let key in c.events) {
  34. const value = c[c.events[key]]
  35. const spaceIndex = key.indexOf(' ')
  36. const part1 = key.slice(0, spaceIndex)
  37. const part2 = key.slice(spaceIndex + 1)
  38. v.el.on(part1, part2, value)
  39. }
  40. }
  41. }
  42. export default c

EventBus

主要用于组件/对象间通信的优化和简化
常用API有:on、trigger、off

  1. on:监听数据的变化,如果数据有变化,直接render(再次将变化后的数据渲染到页面)
  2. this.on('m:updated', () => {
  3. this.render(this.data)
  4. })
  1. tirgger:自动触发事件
  2. update(data) {
  3. Object.assign(m.data, data)//把传进来的data直接放在m.data上
  4. eventBus.trigger('m:updated')//通过trigger自动更新数据
  5. localStorage.setItem('n', m.data.n)//储存数据
  1. off:关闭的意思

表驱动

通过哈希表将事件抽象出来,简化了代码,降低了重复率,这就是表驱动。

对模块化的理解

先说说如果没有模块化,那么前端代码会是怎样的情况:

  • 变量和函数不易维护,容易污染全局作用域
  • 加载资源的方式通过script标签从上到下
  • 大型项目资源难易维护

在较大的项目中使用模块化可以给我们带来很多好处,比如:

  • 解决命名冲突
  • 提高代码复用性
  • 提高代码可维护性
  • 代码之间的耦合度低
  • 多人协作互不干扰