一 什么是MVC
- M(model),数据模型,包含需要操作的数据或信息
- V(view),视图,提供UI界面
- C(controller),控制层,负责监听界面的操作,从而操作相关数据,并做出响应
- 这三层是紧密联系在一起的,但又是互相独立的,每一层内部的变化不影响其他层。每一层都对外提供接口。这样一来,就可以告别意大利面条式代码,进而实现模块化,修改外观或者变更数据都不用修改其他层,大大方便了维护和升级。模块化使得各模块之间解耦,每一个模块不需要知道其他模块如何实现,甚至可以一个模块用jQuery,一个用Vue。
二 eventBus
事件总线,负责通信。它是一种集中式事件处理机制,允许不同的组件之间进行彼此通信而又不需要相互依赖,达到一种解耦的目的。
import $ from 'jquery'
class EventBus {
constructor() {
this._eventBus = $(window)
}
//监听事件
on(eventName, fn) {
return this._eventBus.on(eventName, fn)
}
//触发事件
trigger(eventName, data) {
return this._eventBus.trigger(eventName, data)
}
//取消监听
off(eventName, fn) {
return this._eventBus.off(eventName, fn)
}
}
export default EventBus
三 表驱动编程
对于大批类似但不重复的代码,可以把其中重要的数据做成哈希表,从而可以简化代码。
$btn1.on("click", () => {
let n = parseInt($span.text());
n += 1;
localStorage.setItem("n", n);
$span.text(n);
});
const $btn2 = $(".sub");
$btn2.on("click", () => {
let n = parseInt($span.text());
n -= 1;
localStorage.setItem("n", n);
$span.text(n);
});
const $btn3 = $(".mul");
$btn3.on("click", () => {
let n = parseInt($span.text());
n *= 2;
localStorage.setItem("n", n);
$span.text(n);
});
const $btn4 = $(".divide");
$btn4.on("click", () => {
let n = parseInt($span.text());
n /= 2;
localStorage.setItem("n", n);
$span.text(n);
});
使用表驱动编程后的代码
//表
events: {
"click .add": "add",
"click .sub": "sub",
"click .mul": "mul",
"click .divide": "div",
}
add: () => {
m.data.n += 1;
m.update({ n: m.data.n });
},
sub: () => {
m.data.n -= 1;
m.update({ n: m.data.n });
},
mul: () => {
m.data.n *= 2;
m.update({ n: m.data.n });
},
div: () => {
console.log("a");
m.data.n = m.data.n / 2;
m.update({ n: m.data.n });
},
autobindEvents: () => {
for (let k in c.events) {
const index = k.indexOf(" ");
console.log(k.slice(0, index), k.slice(index + 1), c[c.events[k]]);
v.el.on(k.slice(0, index), k.slice(index + 1), c[c.events[k]]);
}
}
表中key为要获取的dom元素和监听的事件,value为事件触发后要调用的方法。使用autobindEvents方法将元素点击事件与对应的调用函数绑定起来,从而避免了重复写获取dom添加事件的代码。