浅析MVC

103 阅读1分钟

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

const m = {
  data: {
    n: parseInt(localStorage.getItem("n")),  
},};

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

const v = {  el: null,  container: 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.container = $(container);    v.render();  },  render() {    if (v.el === null) {      v.el = $(v.html.replace("{{n}}", m.data.n)).appendTo(v.container);    } else {      const newEl = $(v.html.replace("{{n}}", m.data.n));      v.el.replaceWith(newEl);      v.el = newEl;    }  },};

C:Controller(控制器)负责其他

const c = {  init(container) {    v.init(container);    c.bindEvens();  },  bindEvens() {    v.container.on("click", "#add1", () => {      console.log("1");      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();    });  },};

EventBus 的作用主要是用来实现对象之间的通信,我们可以实现 M、V、C 三个对象之间的通信。

**EventBus的API:
**

app1.js:4 jQuery.fn.init(1)
0: {}
length: 1
__proto__: Object(0)
add: ƒ ( selector, context )
addBack: ƒ ( selector )
addClass: ƒ ( value )
after: ƒ ()
ajaxComplete: 
ƒ ( fn )ajaxError: 
ƒ ( fn )ajaxSend: 
ƒ ( fn )ajaxStart: 
ƒ ( fn )ajaxStop: 
ƒ ( fn )ajaxSuccess: 
ƒ ( fn )arguments: (...)caller: (...)length: 1name: ""prototype: {constructor: ƒ}__proto__: ƒ ()[[FunctionLocation]]: jquery.js:10696[[Scopes]]: Scopes[4]animate: ƒ ( prop, speed, easing, callback )append: ƒ ()appendTo: ƒ ( selector )attr: ƒ ( name, value )before: ƒ ()bind: ƒ ( types, data, fn )blur: ƒ ( data, fn )change: ƒ ( data, fn )children: ƒ ( until, selector )clearQueue: ƒ ( type )click: ƒ ( data, fn )clone: ƒ ( dataAndEvents, deepDataAndEvents )closest: ƒ ( selectors, context )constructor: ƒ ( selector, context )contents: ƒ ( until, selector )contextmenu: ƒ ( data, fn )css: ƒ ( name, value )data: ƒ ( key, value )dblclick: ƒ ( data, fn )delay: ƒ ( time, type )delegate: ƒ ( selector, types, data, fn )dequeue: ƒ ( type )detach: ƒ ( selector )each: ƒ ( callback )empty: ƒ ()end: ƒ ()eq: ƒ ( i )even: ƒ ()extend: ƒ ()fadeIn: ƒ ( speed, easing, callback )fadeOut: ƒ ( speed, easing, callback )fadeTo: ƒ ( speed, to, easing, callback )fadeToggle: ƒ ( speed, easing, callback )filter: ƒ ( selector )find: ƒ ( selector )finish: ƒ ( type )first: ƒ ()focus: ƒ ( data, fn )focusin: ƒ ( data, fn )focusout: ƒ ( data, fn )get: ƒ ( num )has: ƒ ( target )hasClass: ƒ ( selector )height: ƒ ( margin, value )hide: ƒ ( speed, easing, callback )hover: ƒ ( fnOver, fnOut )html: ƒ ( value )index: ƒ ( elem )init: ƒ ( selector, context, root )innerHeight: ƒ ( margin, value )innerWidth: ƒ ( margin, value )insertAfter: ƒ ( selector )insertBefore: ƒ ( selector )is: ƒ ( selector )jquery: "3.5.1"keydown: ƒ ( data, fn )keypress: ƒ ( data, fn )keyup: ƒ ( data, fn )last: ƒ ()length: 0load: ƒ ( url, params, callback )map: ƒ ( callback )mousedown: ƒ ( data, fn )mouseenter: ƒ ( data, fn )mouseleave: ƒ ( data, fn )mousemove: ƒ ( data, fn )mouseout: ƒ ( data, fn )mouseover: ƒ ( data, fn )mouseup: ƒ ( data, fn )next: ƒ ( until, selector )nextAll: ƒ ( until, selector )nextUntil: ƒ ( until, selector )not: ƒ ( selector )odd: ƒ ()off: ƒ ( types, selector, fn )offset: ƒ ( options )offsetParent: ƒ ()
on: ƒ ( types, selector, data, fn )one: ƒ ( types, selector, data, fn )outerHeight: ƒ ( margin, value )outerWidth: ƒ ( margin, value )parent: ƒ ( until, selector )parents: ƒ ( until, selector )parentsUntil: ƒ ( until, selector )position: ƒ ()prepend: ƒ ()prependTo: ƒ ( selector )prev: ƒ ( until, selector )prevAll: ƒ ( until, selector )prevUntil: ƒ ( until, selector )promise: ƒ ( type, obj )prop: ƒ ( name, value )push: ƒ push()pushStack: ƒ ( elems )queue: ƒ ( type, data )ready: ƒ ( fn )remove: ƒ ( selector )removeAttr: ƒ ( name )removeClass: ƒ ( value )removeData: ƒ ( key )removeProp: ƒ ( name )replaceAll: ƒ ( selector )replaceWith: ƒ ()resize: ƒ ( data, fn )scroll: ƒ ( data, fn )scrollLeft: ƒ ( val )scrollTop: ƒ ( val )select: ƒ ( data, fn )serialize: ƒ ()serializeArray: ƒ ()show: ƒ ( speed, easing, callback )siblings: ƒ ( until, selector )slice: ƒ ()slideDown: ƒ ( speed, easing, callback )slideToggle: ƒ ( speed, easing, callback )slideUp: ƒ ( speed, easing, callback )sort: ƒ sort()splice: ƒ splice()stop: ƒ ( type, clearQueue, gotoEnd )submit: ƒ ( data, fn )text: ƒ ( value )toArray: ƒ ()toggle: ƒ ( speed, easing, callback )toggleClass: ƒ ( value, stateVal )trigger: ƒ ( type, data )triggerHandler: ƒ ( type, data )unbind: ƒ ( types, fn )undelegate: ƒ ( selector, types, fn )unwrap: ƒ ( selector )val: ƒ ( value )width: ƒ ( margin, value )wrap: ƒ ( html )wrapAll: ƒ ( html )wrapInner: ƒ ( html )Symbol(Symbol.iterator): ƒ values()__proto__: Objectconstructor: ƒ Object()hasOwnProperty: ƒ hasOwnProperty()isPrototypeOf: ƒ isPrototypeOf()propertyIsEnumerable: ƒ propertyIsEnumerable()toLocaleString: ƒ toLocaleString()toString: ƒ toString()valueOf: ƒ valueOf()__defineGetter__: ƒ __defineGetter__()__defineSetter__: ƒ __defineSetter__()__lookupGetter__: ƒ __lookupGetter__()__lookupSetter__: ƒ __lookupSetter__()get __proto__: ƒ __proto__()set __proto__: ƒ __proto__()

API举例:

on方法,监听事件

trigger方法,触发事件

**off方法,**用于取消对象监听。

可以监听rander的变化,页面的data.n一变,即可自动rander视图 。

表驱动编程:

**这里的表指的是 哈希表 ,这是一种很重要的编程思想。它的核心就在于通过哈希表的形式把重复的代码进行剥离。
**

// jQuery 风格写法
$('#el1').on('事件A', fn1)
$('#el2').on('事件B', fn2)
$('#el3').on('事件C', fn3)
$('#el4').on('事件D', fn4)
$('#el5').on('事件E', fn5)

const evevts = {
  "#el1 事件A": "fn1",
  "#el2 事件B": "fn2",
  "#el3 事件C": "fn3",
  "#el4 事件D": "fn4",
  "#el5 事件E": "fn5"
}

const eventFunctions = {
  fn1: function() {},
  fn2: function() {},
  fn3: function() {},
  fn4: function() {},
  fn5: function() {}
}
// 通过一个公共的函数即可实现所有事件的调用
function autoBindEvents() {
  for(let key in events) {
    const spaceIndex = key.indexOf(' ')
    const el = key.splice(0, spaceIndex) // 获取元素
    const event = key.splice(spaceIndex+1) // 获取元素需要执行的事件
    const fn = eventFunctions[events[key]] // 执行事件后的函数
    $(el).on(event, fn)
  }
}

模块化:

代码采用模块化后,可以做到互不影响 A 模块的改变并不会影响 B 模块的使用,这样可以使得我们的程序更加清晰和容易维护。

文章部分内容参考zhuanlan.zhihu.com/p/162795201…