MVC 三个对象
MVC 的三个对象,分别为 M、V、C
- M - Model(数据模型)负责操作所有数据。
- V - View(视图)是直接面向最终用户的“视图层”,负责所有 UI 界面。
- C - Controller(控制器)负责根据用户从“视图层”输入的指令,选取“数据层”中的数据,然后对其进行相应的操作,产生最终结果。
const Model = {
data(){} //保存数据
create(){}, //增
delete(){}, //删
undate(){}, //改
get(){} //查
}
const View = {
el:null, //接受一个容器
html: ``, //生成HTML
init(){}, //初始化容器
render() //页面渲染
}
const Controller = {
init(){}, //初始化容器
events:{}, //用户操作事件
bindEvents(){} //绑定事件,响应用户操作
}
EventBus
EventBus 是一种设计模型或框架,主要用于组件/对象间通信
常用 API
on监听事件trigger自动触发事件off取消监听
用法:
1. 封装 EventBus
// EventBus.js
import $ from 'jquery'
class EventBus {
constructor() {
// 从 window 上引用来的
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
2. 用cosnt e = new EventBus()
在 a.js 文件里,new EventBus()即可直接使用on、trigger、off等方法。
// a.js
import EventBus from 'EventBus.js'
const e = new EventBus()
e.on()
e.trigger()
e.off()
或者用 class 继承的方法
- 让 Model/View 继承 EventBus
// Model.js
import EventBus from './EventBus'
class Model extends EventBus {
constructor(options) {
super()
const keys = ['data', 'update', 'create', 'delete', 'get']
keys.forEach((key) => {
if (key in options) {
this[key] = options[key]
}
})
}
create(){}
delete(){}
update(){}
get(){}
}
export default Model
// View.js
import $ from 'jquery'
import EventBus from 'EventBus'
class View extends EventBus{
// constructor({el, html, render, data, eventBus, events}) {
constructor(options) {
super() // EventBus#constructor()
Object.assign(this, options)
this.el = $(this.el)
this.render(this.data)
this.autoBindEvents()
// 监听数据变化
this.on('m:updated', () => {
this.render(this.data)
})
}
}
export default View
3. 在 app.js 里面,使用trigger,自动触发事件
update(data) {
Object.assign(m.data, data)//把传进来的data直接放在m.data上
eventBus.trigger('m:updated')//通过trigger自动更新数据
localStorage.setItem('n', m.data.n)//储存数据
}
表驱动编程
表驱动法是一种编程模式,从表(哈希表)里面查找信息而不是使用逻辑语句(if…else…switch),可以减少重复代码,只将重要的信息放在表里,然后利用表来编程,与逻辑语句相比较有着更稳定的复杂度。
举例,以下代码里面就有很多大批类似但不重复的代码,
// 没有使用表驱动编程的代码
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)
})
}
使用 表驱动 取出一个事件的哈希表,清晰的分明了数据和逻辑。
// 运用了表驱动编程的代码(将事件提取出一个哈希表,使逻辑和数据分离开)
events:{
'click #add1':'add',
'click #minus1':'minus',
'click #mul2':'mul',
'click #divide2':'div'
},
add(){
m.update({n:m.data.n + 1})
},
minus(){
m.update({n:m.data.n - 1})
},
mul(){
m.update({n:m.data.n * 2})
},
div(){
m.update({n:m.data.n / 2})
}
如何理解模块化
- 代码模块化之后,无论是代码的整体性还是后期进行代码维护,都变的清晰简单了起来。例如与逻辑相关的代码统一放到 JS 文件中,与视图相关的统一放到 html 文件中,与样式相关的统一放到 css 文件中。
- 业务模块化之后可以使业务流程更为清晰,便于开展工作,各个业务模块之间负责自己模块的业务,也避免了一些不必要的麻烦,使得工作的效率也会更高。
- 模块化我觉得是一种高效的思想,这在编程过程中提供了一种优化代码以及重构代码的方向。