所谓事不过三,一个事情不应该重复做三遍以上,那么在追求简洁美的编程中更是体现的淋漓尽致,MVC 即 model view controller,一个以实现用户界面与业务逻辑分离,实现组件重用为目标的架构设计模式。
- model 数据层
- view 视图层
- controller 控制器层
他们之前的关系如下图所示
实线即方法调用,虚线即事件通知
MVC将代码模块化,分为3个模块,每个模块负责每个模块的事情,使得代码相互独立,互不影响,却又紧密连接,模块之间不需要了解对方的内部构造,只需要对外提供一个接口
- model ,负责保存数据和操作所有的数据
const model ={
data:{
//存放数据
n:parseInt(localStorage.getItem('n'))
},
update(data){
//更新数据
},
create(data){
//创建数据
},
get(data){
//查询数据
},
delete(data){
//删除数据
}
}
- view,负责所有的ui界面,
const v={
el:null,
html:`
<div>
<div class="output">
<span>{{n}}</span>
</div>
<div class="actions">
<button id="add1">+1</button>
</div>
</div>`,
init(el) {
//初始化页面
v.el =$(el)
v.render()
},
render(n){
//渲染页面
if(v.el.children.length !== null)v.el.empty()
$(v.html.replace('{{n}}',n)).appendTo($(v.el))
}
}
- controller,负责监听用户事件,并且调用数据层和视图层
const controller = {
init(container) {
//调用视图层的页面初始化和渲染
v.init(container)
v.render(m.data.n)
//绑定事件监听
c.autoBindEvents()
//监听用户事件
eventBus.on('m:updated', () => {
v.render(m.data.n)
})
},
events: {
//将事件封装成表对象
'click #add1': 'add',
},
add() {
m.update({ n: m.data.n + 1 })
},
autoBindEvents() {
//表驱动编程,查询表events,给目标对象绑定事件
for (let key in c.events) {
const part = key.split(' ')
const value = c[c.events[key]]
v.el.on(part[0], part[1], value)
}
}
}
注意点:
- 表驱动编程,不使用if else等逻辑语句,通过将选项存入表中,对表进行查询
- eventBus即事件总线,用于绑定事件,接触绑定事件,触发事件
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)
}
}
MVC的优点:代码模块化,分工明确,提高工作效率。耦合性低,增加了组件的重用性,降低了维护成本。
MVC的缺点:系统结构复杂,实现起来比较困难,所以小型项目不适用,只适合大型项目,view和controller联系过于紧密,mvc将其分离,导致应用的范围会受到限制,虽然mvc对代码进行了模块化处理,但是由于关联性,很难实现独立重用。