浅析MVC

159 阅读3分钟

1.MVC是什么?

  • M:模型(Model):数据保存

  • V:视图(View):用户界面

  • C:控制器(Controller):业务逻辑

这是一个设计框架,一个软件的实现可以按照这三个部分来实现,它们之间互相通信,根据通信的方式不同,衍生了其他几种不同的设计模式。

传统意义上的MVC各个部分之间的通信是单向的

  • View 传送指令到 Controller

  • Controller 完成业务逻辑后,要求 Model 改变状态

  • Model 将新的数据发送到 View,用户得到反馈

各个部分伪代码的实现

1.Model

Model = {
    data: { 程序需要操作的数据或信息 },
    create: { 增数据 },
    delete: { 删数据 },
    update(data) { 
       Object.assign(m.data, data) //使用新数据替换旧数据
       eventBus.trigger('m:upate') // eventBus触发'm:update'信息, 通知View刷新 
    },
    get:{ 获取数据 } 
}

2.View

View = {
    el: 需要刷新的元素,
    html: `<h1>M V C</h1>....显示在页面上的内容`
    init(){
        v.el: 需要刷新的元素
    },
    render(){ 刷新页面 }
}

3.Controller

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


2.EventBus

把所有对象看成一个个点,了解点与点之间的通信,找到一个专用的点负责通信,这个点就是eventBus。 其实jquery和vue构造出来的对象都有监听事件的方法,我们只需要构造一个对象,然后调用他的on 和 trigger方法就可以实现组件之间的通信。

下面介绍几个vue常用的事件api及其内部实现:

1.$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)
}

2.$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
 }


3.$emit 事件的触发(trigger)

$emit(eventName,[params]) 
//参数1:事件名称 参数2:[需要传递的参数]
//判断当前事件的名称是否存在,如果存在则遍历数组,得到所有的函数,
//并执行。然后将params当做实参传递到函数中去
const eventList = {};
const $emit = (eventName,params)=>{
    if(eventList[eventName]){
         let arr = eventList[eventName];
         arr.map((cb)=>{
             cb(params)
         })
    }
}



3.表驱动编程

面对大批不重复的代码时,找到重要数据,做成哈希表来简化代码(数据结构红利)

伪代码实例:

function age(name){
    if(name==="小明"){
        console.log("年龄是"+10)
    }else if(name==="小白"){
        console.log("年龄是"+14)
    }else if(){
       
    }
    //....等等
}

假如我们要写一个查询年龄的函数,如果用if else语句写,那么有多少人我们就得写多少个if else语句,这样我们的代码量是线性增长的,如果我们用一个哈希表来记录这些映射关系会怎样

const list={
    "小明":10,
    "小白":14,
    //等等...
}
function age2(name){
    if(name in list){
        console.log(name+"的年龄是"+list[name])
    }else{
        console.log("查无此人")
    }
}

这样我们的数据部分就和代码部分分离了,函数主体只是去表中查找然后输出结果,这就是表编程的基本思想。if else的复杂度为n,表编程的复杂度为1。代码数据越多表编程优势越明显。


4.我理解的模块化

我理解的模块化是一种体现在代码上的思维方式上的简洁化。这种简洁并不是一种看的见的简洁,不能以代码的行数来定义的简洁。这种思维方式上的简洁化更有利于我们的技术走向更高的平台。


本博客参考下面博客写成

链接:https://juejin.cn/post/6844904055752376333