《我们眼中的 MVC》

110 阅读2分钟

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

  • M 是 Model,数据模型,负责数据相关的任务
//接口
const m = {
    data : {
    //初始化数据
    index: parseInt(localStorage.getItem('n'))
    },
    create(){},
    delete(){},
    updata(data){
    Object.assign(m.data, data)//将data的值复制给m.data 
    eventBus.trigger('m:updated')//触发事件 
    localStorage.setItem('n', m.data.n)//存入数据
    },
    get(){}
}
  • V 是 View,视图,负责用户界面
//属性
const v ={
 el:要刷新的元素 
 html:`展示在页面上的内容` 
 init() { v.el = $(刷新的元素) v.render()//刷新页面 }, 
 render()//刷新页面   
}
  • C 是 Controller,控制器,负责监听用户事件,然后调用 M 和 V 更新数据和视图
//方法
let c = {
    init(){
        v.init()//初始化View
        v.render()//第一次渲染页面
        c.autoBindEvents()//自动的事件绑定
        eventBus.on('m:update',()=>{
        v.render()
        }//当enentsBus触发'm:update'是View刷新
    },
    events:{事件以哈希表的方式记录存储},

      add() {+具体实现},
      minus() {-具体实现},
      mul() {*具体实现},
      div() {/具体实现},
      
    autoBindEvents(){自动绑定事件}
}

2. EventBus 有哪些 API,是做什么用的,给出伪代码示例

eventBus即事件总线,用于模块间的通讯, ​view 组件层面,父子组件、兄弟组件通信都可以使 ​eventbus 处理 简而言之,就是用来事件通信

eventBus主要用于对象间的通信,满足最小知识原则,m与v之间互不知道细节,却可以调用对方功能。

基本的api有

on(监听事件),trigger(emit)(触发事件),off(取消监听)方法。

EventBus 事件发布-订阅总线,提供事件发布、订阅等功能

// 订阅者
$(document).on('say', function() {  console.log('hi')})
// 发布者
$(document).trigger('say')
// 其中 say 是事件
//EventBus.js
class EventBus {
    constructor() {
        this._eventBus = $(window) //引入jquery中的eventBus
    }
    on(eventName, fn) {
        return this._eventBus.on(eventName, fn)
    }
    trigger(eventName, data) {
        return this._trigger.trigger(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()

EventBus3.0源码地址:github.com/greenrobot/…

3. view=render(data)概念

view = render(data) //渲染数据(view:视图,页面)

只要改变data就能得到相应的view

4. 表驱动编程是做什么的

所谓表驱动法(Table-Driven Approach),是指用查表的方法获取值。 表驱动法是一种编程模式(scheme)——从表里面查找信息而不使用逻辑语句(if和case)。事实上,凡是能通过逻辑语句来选择的事物,都可以通过查表来选择。对简单的情况而言,使用逻辑语句更为容易和直白。但随着逻辑链的越来越发杂,查表法也就愈发显得更具吸引力。

顾名思义通过哈希表等来驱动一系列事件、函数的变成。使代码变得更简洁,易于维护。

1、没有使用表驱动编程的代码

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)
  })
}

2、运用了表驱动编程的代码(将事件提取出一个哈希表,使逻辑和数据分离开)

events: {
  'click #add1' : '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})
}

数据驱动的一些优势:

  • 可读性更强
  • 更容易修改,也就是说易于扩展,能够更好的面向变化
  • 更易重用

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

1、模块化代码之前,我们写的代码被称之为意大利面条式代码;

2、学习了模块化的之后,我们把数据模型,负责数据相关的任务放进Model;

视图,负责用户界面放入View;

控制器,负责监听用户事件放入Controller;

3、业务模块化之后可以使业务流程更为清晰,便于开展工作,各个业务模块之间负责自己模块的业务,也避免了一些不必要的麻烦,使得工作的效率也会更高。

4、可以使用 export default x 将一个变量默认导出给外部使用;

可以使用 import {x} from './xxx.js' 引用另一个模块导出的名为 x 的变量

每个板块的业务代码都能用不同的技术写,且互不干扰。