一、MVC 三个对象
- M : 模型(Model),用来数据保存。
- V : 视图 (View) , 用户界面。
- C : 控制器(Controller),业务逻辑。
各个部分的伪代码实现
Model
Model ={
data:{程序需要操作的数据或信息},
create:{增数据},
delete:{删数据},
update(data) {
Object.assign(m.data,data) //使用新数据替换旧数据
eventBus.trigger('m:updata') // eventBus触发'm:updata'信息,通知View刷新
},
get:{获取数据}
}
View
View = {
el:需要刷新的元素
html: `<h1>M V C</h1>...显示在页面上的内容`
init(){
v.el:需要刷新的元素
},
render(){刷新页面}
}
Controller
Controller = {
init(){
v.init() // View初始化
v.render() // 第一次渲染
c.autoBindEvents() // 自动的事件绑定
eventBus.on('m:updata',() => { v.render() }) // 当eventBus触发'm:updata'时View刷新
},
events:{事件以哈希表方式记录},
method(){
data = 改变后的数据
m.updata(data)
},
autoBindEvents(){ 自动绑定事件 }
}EventBus
二、eventBus
- $on事件的订阅
$on(eventName,callback)
//参数1:事件名称 参数2:事件函数
//判断当前事件名称是否存在,如果不存在则创建一个key值为事件名称
//value为一个数组 将callback push到数组中
const eventList = {};
const $on = (eventName,callback)=>
if(!eventList[eventName]){
eventList[eventName] = [];
}
eventList[eventName].push(callback)
}
- $off事件解绑
$off(eventName,[callback])
//参数1:事件名称 参数2:[事件函数]
//判断当前事件名称是否存在,如果存在继续判断第二个参数是否存在,如果存在则找到相对应的下标,然后将函数在数组中移除
//如果不存在则将整个数组清空
const eventList = {};
const $off = (eventName,callback)=>{
if(eventList[eventName]{
if(callback){
let index = eventList[eventName.indexOf(callback);
eventList[eventName].splice(index,1)
}
}else{
eventList[eventName].length = 0
}
}
export default = {
$on,
$emit,
$off,
}
- $emit事件的触发
$emit(eventName,[params])
//参数1:事件名称 参数2:[需要传递的参数]
//判断当前事件的名称是否存在,如果存在则遍历数组,得到所有的函数,
//并执行,然后将params当做实参传递到函数中去
const eventList = {};
const $emit = (eventName,params)=>{
if(eventList[eventName]{
let arr = eventList[eventName];
arr.map((cb)=>{
cb(params)
})
}
}
三、表驱动编程
表驱动编程是一种很重要的编程思想,它的理念是从大量相似的代码中抽取出本质的东西,组成哈希表,利用表进行编程,以减少重复代码。
例如,需要给多个元素绑定不同的事件,直觉上我们会一个个地罗列:
// jQuery 风格写法
$('#el1').on('事件A', fn1)
$('#el2').on('事件B', fn2)
$('#el3').on('事件C', fn3)
$('#el4').on('事件D', fn4)
$('#el5').on('事件E', fn5)
一旦重复次数过多,代码就会变得冗余、臃肿。纵观整体,可以发现每行代码最关键的信息其实就是'#el'、'事件'和fn,将关键信息抽离,组成一个对象:
const events = {
'#el1 事件A': 'fn1',
'#el2 事件B': 'fn2',
'#el3 事件C': 'fn3',
'#el4 事件D': 'fn4',
'#el5 事件E': 'fn5'
}
const eventFunctions = { //事件处理函数
fn1(){}
fn2(){}
fn3(){}
fn4(){}
fn5(){}
}
如此,就去除了所有重复的代码。乍看可能觉得更复杂了,但是当事件越来越多时,其简洁性就越来越显著。而且后续再添加新的事件时,只需在events对象中添加即可,非常便捷。
四、模块化理解
现代的前端应用程序功能越来越强大,代码量也越来越庞大。因此,将网页应用分为各个独立的模块单独开发,每个模块之间互不影响,可以使程序的结构更加清晰,方便维护。 现代浏览器已经原生支持了模块功能,使用export和import语句就可以实现。 在以前,实现一个应用需要引入html、css、js。有了模块化的思想,只需引入一个js就可以实现。 在main.js中引入各个模块的js,各个js再各自引用自己的css、创建自己的html。 我们还可以把这些模块用到的类,也封装成单独的模块,然后再将其引入到各个模块中。 如此,所有的模块都是独立的,互不影响,代码的层次结构会变得异常清晰。