一.前言
MVC是一种架构设计模式,它通过关注点分离鼓励改进应用程序组织。在过去,MVC被大量用于构建桌面和服务器端应用程序,如今Web应用程序的开发已经越来越向传统应用软件开发靠拢,Web和应用之间的界限也进一步模糊。传统编程语言中的设计模式也在慢慢地融入Web前端开发。由于前端开发的环境特性,在经典MVC模式上也引申出了诸多MV*模式,被实现到各个Javascript框架中都有多少的衍变 。
mvc是为了解决页面代码重复问题,优化代码,
把重复的代码封装了,即放在一个函数里面去调用
二.MVC是什么
每个模块都可以写成三个对象,分别是M,V,C
1.M:Model,负责所有数据
- 模型model用于封装与应用程序的业务逻辑相关的数据以及对数据的处理方法。
- 会有一个或多个视图监听此模型。一旦模型的数据发生变化,模型(M)将通知有关的视图(V)。
Model = {
data: { 需要用到的数据 },
create(): { 增数据 },
delete(): { 删数据 },
update() {更新数据},
get():{ 获取数据 }
}
2.V:View视图,负责所有UI界面
- 视图view是它在屏幕上的表示,描绘的是model的当前状态。
- 当模型的数据发生变化,视图相应地得到刷新自己的机会。
View = {
el:null,
html: `......` //视图模板
init(){初始化页面},
render(){ 刷新页面 }
}
3.C:Controller负责其他
- 控制器controller定义用户界面对用户输入的响应方式,起到不同层面间的组织作用,用于控制应用程序的流程,它处理用户的行为和数据model上的改变。
- C里面主要是放一些事件的操作,如:click、on等等;这里面又设计到EventBus、表驱动编程等等。
Controller = {
init() {
v.init() // View初始化
v.render() // 第一次渲染
c.autoBindEvents() // 自动的事件绑定
eventBus.on('m:update', () => { v.render() }) // 当eventBus触发'm:update'时View刷新
},
events:{ 事件以哈希表方式记录 },
method() {
data = 改变后的新数据
m.update(data)
},
autoBindEvents() { 自动绑定事件 }
}
三.EventBus有哪有API,是做什么用的,给出伪代码示例
1.目的:解决模块之间通信的问题,view组件层面,父子组件,兄弟组件通信都可以用eventbus处理
2.API
on: 监听事件的变化
this.on('m:updated', () => {
this.render(this.data)
})
trigger:自动触发事件 当一个事件执行,eventBus触发m:updated
update(data) {
Object.assign(m.data, data)//把传进来的data直接放在m.data上
eventBus.trigger('m:updated')//通过trigger自动更新数据
localStorage.setItem('n', m.data.n)//储存数据
}
四.表驱动编程是做什么的
表驱动方法是一种使你可以在表中查找信息,而不必用逻辑语句(if 或 case)来把他们找出来的方法。
事实上,任何信息都可以通过表来挑选。在简单的情况下,逻辑语句往往更简单而且更直接。
但随着逻辑链的复杂,表就变得越来越富于吸引力了。
function translate(term) {
if (term === '1') {
return '一'
} else if (term === '2') {
return '二'
} else if (term === '3') {
return '三'
} else {
return '???'
}
}
// 如果想添加一个新的名词翻译,需要再添加一个if-else逻辑,例如:
function translate(term) {
if (term === '1') {
return '一'
} else if (term === '2') {
return '二'
} else if (term === '3') {
return '三'
} else if (term === '4') {
// 此处添加了一个新的名词翻译
return '四'
} else {
return '???'
}
}
表驱动编程:
function translate(term) {
let terms = {
'1': '一',
'2': '二',
'3': '三'
}
return terms[term];
}
// 如果想添加一个新的名词翻译,只需要在terms中添加一个新的表项,不需要修改整个逻辑
function translate(term) {
let terms = {
'1': '一',
'2': '二',
'3': '三'
'4': '四' // 添加一个新的名词翻译
}
return terms[term];
}
总结:通过哈希表将事件全部抽出来后代码就会简洁很多,这,就是表驱动编程。
五.如何理解模块化的
- 将一个复杂的程序依据一定的规则封装成几个块,并进行组合在一起
- 块的内部数据与实现是私有的,只是向外部暴露了一些
模块化的好处:
- 避免命名冲突(减少命名空间污染)
- 更好的分离, 按需加载
- 更高复用性
- 高可维护性