MVC是什么
前言:个人认为MVC是一个万金油,所有的页面都可以使用MVC优化代码结构。
每个模块都可以写成三个对象,分别是M、V、C
- M-Model(数据模型),负责操作所有数据
- V-View(视图),负责所有UI界面
- C-Controller(控制器),负责其它
代码示例
- M-Model(数据模型),负责操作所有数据
const m = {
data:{需要操作的事件信息}
create:{}
delete:{}
updtae (data){
Object.assign(m.data, data) //更新数据
eventBus.trigger('m:updated') //eventbus触发
}
get:{获取数据}
}
- V-View(视图),负责所有UI界面
const v ={
el:需要刷新的元素
html(index)=>{
return`
<div>...</div>
`
}
init(){
v.el:需要刷新的元素
},
render(){}
}
- C-Controller(控制器),负责其它
const c = {
init(){
v.init() //初始化
v.render() //第一次渲染
c.autoBindEvents() // 自动的事件绑定
ntBus.on('m:update', () => { v.render() }) // 当eventBus触发'm:update'时View刷新
},
events:{ 事件记录 },
autoBindEvents() {
自动绑定事件
}
}
}
eventbus
- 主要用于对象间的通信
- 使用eventbus可以满足最小知识原则,m和v不知道对方的细节,但是可以调用对方的功能
- ventbus提供了on.off.trigger等API,其中on用于事件监听,trigger用于事件触发
const eventBus = $(window)
const m ={
data:{...}
update(data){
eventBus.trigger(A)
}
}
eventBus.on(A, ()=>{
v.render(m.data)
})
表驱动编程
表指的是哈希表,表驱动编程可以减少重发代码,只将重要信息放在表里,然后利用表进行编程
例如给多个元素绑定不同事件
$('#bl1').on('事件A', fn1)
$('#bl2').on('事件B', fn2)
$('#bl3').on('事件C', fn3)
$('#bl4').on('事件D', fn4)
$('#bl5').on('事件E', fn5)
我们发现一旦代码重复次数过多 就会变的冗余,分析代码发现每行代码最关键的信息其实就是'#el'、'事件'和fn,所以我们可以将关键信息抽离,组成一个对象:
const events = {
'#bl1 事件A': 'fn1',
'#bl2 事件B': 'fn2',
'#bl3 事件C': 'fn3',
'#bl4 事件D': 'fn4',
'#bl5 事件E': 'fn5'
}
const eventFunctions = { //事件处理函数
fn1(){}
fn2(){}
fn3(){}
fn4(){}
fn5(){}
}
然后创建一个函数,给这些元素绑定相应的事件:
function autoBindEvents(){
for(let key in events){
const spaceIndex = key.indexOf(' ')
const element = key.slice(0, spaceIndex) //得到各个'#el'
const event = key.slice(spaceIndex + 1) //得到各个'事件'
const fn = eventFunctions[events[key]] //得到各个fn
$(element).on(event, fn) //绑定事件
}
}
经过一系列的封装,最终我们得到这样的代码,当事件越多时,其简洁性就越高,每当有新的事件时,我们只需在event中添加即可
模块化编程
接触过模块化编程思想后,来说一下自己的理解,模块顾名思义就是一块一块的内容。在现实开发中,一个项目往往会涉及到多个功能模块,为了能够提升开发的效率,我们会选择多模块并行开发。
在main.js中引入各个模块的js,各个js再各自引用自己的css、创建自己的html。我们还可以把这些模块封装成单独的模块,然后再将其引入到各个模块中。
如此,所有的模块都是独立的,互不影响,代码的层次结构会变得异常清晰,也方便后期的代码优化。