什么是MVC
MVC是一种设计模式,我们在JS代码中应用MVC设计模式主要是为了封装重复的代码,使代码更简洁,而且MVC设计模式的模块化思想让我们能更方便地辨别代码的内容和功能,避免写完代码过几天就忘记各部分代码是实现什么功能的现象。
MVC设计模式把应用分成三个部分:
M-Model
数据模型,负责操作所有数据。伪代码如下:
Model = {
data: {应用要用到的数据挂到data属性上},
create: { 增数据 },
delete: { 删数据 },
update(data) {
//更改数据
Object.assign(m.data, data) //使用新数据替换旧数据
eventBus.trigger('m:upate') // eventBus触发'm:update'信息, 通知View刷新
},
get:{ 获取数据 }
}
V-View
视图,负责所有UI界面,伪代码如下:
View = {
el: 需要刷新的元素,
html: `<div>...给用户呈现的HTML内容...</div>`
init(){
//页面初始化方法
v.el: 需要刷新的元素
},
render(){ 页面渲染方法 }
}
C-Controller
控制器,负责其他,伪代码如下:
Controller = {
init(){
v.init() // View初始化
v.render() // 第一次渲染
c.autoBindEvents() // 事件绑定
eventBus.on('m:update', () => { v.render() }) // eventBus监听数据变更事件,View自动刷新
},
events:{ 事件以哈希表方式存储 },
method() {
{增删改查等操作数据的方法}
},
autoBindEvents() { 绑定事件函数 }
}
EventBus
eventBus可以实现对象之间的通信,自动监听事件作出的改变。jquery和vue构造出来的对象其实都继承了用class封装的eventBus,所以只要在对象后面加.on 、.off、.trigger等就能直接使用eventBus的方法。
EventBus主要的api有:
- on
- off
- emit(在jquery里面是trigger,在vue里面是emit)
$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)
})
}
}
表驱动编程
表驱动编程也是一种设计模式————从表里查找信息而不是使用逻辑语句if或者case。凡是能通过逻辑语句来选择的都可以改写成哈希表查询。在代码比较简单的情况下,可能使用if和else if等逻辑语句显得更直白易懂,但是当代码很复杂的时候,大量的if语句将占据大篇幅的代码行,而使用表驱动编程的思想无论代码查找信息的量有多大,代码量都可以稳定控制在比较短的篇幅内。
举个简单的实例:
function age(name){
if(name==="小明"){
console.log("年龄是"+10)
}else if(name==="小白"){
console.log("年龄是"+14)
}else if(){
}
//...etc
}
以上是一个根据姓名查询对应年龄的函数,如果用if else语句实现,那么数据量有多少个,就得写多少个if else语句,如果有1000个人,那么就有1000个if else,代码量吓人。那么如果用哈希表的方式实现年龄查询呢?
const list={
"小明":10,
"小白":14,
//...etc
}
function age2(name){
if(name in list){
console.log(name+"的年龄是"+list[name])
}else{
console.log("没有这个人")
}
}
这样做数据就和逻辑判断分离了,无论数据量有多少个,实现查询的部分代码量都是固定的,只需要写一个遍历哈希表的函数就可以实现查询功能,如果有1000个人,充其量也就是哈希表长一点,有1000个元素,查询部分的代码完全不用改动。
我眼中的模块化编程
我觉得模块化最大的好处不在于其方便易用,模块化编程的实现离不开代码的封装,而对于我这种初学者而言,要理解通用代码的抽象和封装的过程显然有点困难了,我觉得模块化最好的地方是便于管理,可以很方便地知道哪部分的代码是用来为哪个功能服务的,尤其是对于一些别人写的项目或者自己写的但是已经搁置了很久的项目,如果是模块化的项目理解代码起来会基本没有障碍。