IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> 浅析 MVC -> 正文阅读

[开发测试]浅析 MVC

一、何为MVC?

每个模块都可以写成三个对象,分别是 M、V、C

  • M 是 Model,数据模型,负责数据相关的任务
  • V 是 View,视图层,负责用户界面
  • C 是 Controller,控制器,负责监听用户事件,然后调用 M 和 V 更新数据和视图

接下来以代码展示三部分的工作内容

  • Model 数据模型
let Model={
    data:{数据源},
    create:{增加数据},
    delete:{删除数据},
    update(data){ 
        Object.assign(m.data,data) // 用新数据替换旧数据
        eventBus.trigger('m:update') // eventBus触发'm:update'信息,通知View刷新界面
    },
    get:{获取数据}
}
  • View 视图层
let View={
    el: 要刷新的元素,
    html:'要显示在页面上的刷新内容'
    init(){
        v.el: 初始化需要刷新的元素
    },
    render(){
        刷新页面
    }
}
  • Controller 控制器
let Controller={
    init(){
        v.init() // 初始化View
        v.render() // 第一次渲染页面
        c.autoBindEvents() // 自动的事件绑定
        eventBus.on('m:update',()=>{v.render()} // 当enentsBus触发'm:update'是View刷新
    },
    events:{事件以哈希表的方式记录存储},
    // 例如:
   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})
    },
    method(){
        data=新数据
        m.update(data) // controller 通知model去更新数据
    },
    autoBindEvents(){
    	for (let key in c.events) { // 遍历events表,然后自动绑定事件
      const value = c[c.events[key]]
      const spaceIndex = key.indexOf(' ')
      const part1 = key.slice(0, spaceIndex) // 拿到 'click'
      const part2 = key.slice(spaceIndex + 1)  // 拿到'#add1'
      v.el.on(part1, part2, value)
    }
}

二、EventBus

何为 EventBus ?

EventBus 主要用于对象之间的通信,比如在上面的例子中,Model 数据模型 和View 视图模型彼此不知道彼此的存在,但是又需要通信,于是就要用到EventBus

使用 eventBus 可以满足最小知识原则,m 和 v 互相不知道对方的细节,但是却可以调用对方的功能

EventBus 有哪些 API ?

eventBus 提供了 on、off 和 trigger 等 API,on 用于监听事件,trigger 用于触发事件

接下来以代码展示 EventBus 的作用

const m = {
  ....
  update(data) {
    Object.assign(m.data, data)
    eventBus.trigger('m:updated')  // 通知一下view层,我已经更新了数据,view该开始工作了
    localStorage.setItem('n', m.data.n)
  },
  ....
}

// 然后在controller,controller会用 on 监听事件, 然后通知 view 模型去重新渲染页面

const c = {
  init(container) {
    v.init(container)
    v.render(m.data.n) // view = render(data)
    c.autoBindEvents()
    eventBus.on('m:updated', () => {   // controller会用 on  监听事件,
      // 然后通知 view 模型去重新渲染页面
      console.log('here')
      v.render(m.data.n)
    })
  },
  ... 
}

三、表驱动编程

当我们需要判断3种以上的情况,做出相应的事情,往往需要写很多很多的 If else,为了增强代码的可读性,我们可以用表驱动编程,把用来做 If 条件判断的值存进一个哈希表,然后从表里取值

我们对四个按钮分别绑定click事件,然后再分别写四个回调函数,修改值

$button1.on('click', () => {
    let n = parseInt($number.text())
    n += 1
    localStorage.setItem('n', n)
    $number.text(n)
})

$button2.on('click', () => {
    let n = parseInt($number.text())
    n -= 1
    localStorage.setItem('n', n)
    $number.text(n)
})

$button3.on('click', () => {
    let n = parseInt($number.text())
    n = n * 2
    localStorage.setItem('n', n)
    $number.text(n)
})

$button4.on('click', () => {
    let n = parseInt($number.text())
    n = n/2
    localStorage.setItem('n', n)
    $number.text(n)
})

--------用事件委托后-------
  const c = {
    init(container) {
        v.init(container)
        v.render(m.data.n)
        c.BindEvents()
    }
    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)
        })
    }
}

改用表驱动编程

  • 绑定加减乘除按钮的父元素,就只用一个事件监听器
  • 用哈希表存下按钮和按钮对应的操作?
const c = {
  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})
  },
  autoBindEvents() {
    for (let key in c.events) {
      const value = c[c.events[key]]
      const spaceIndex = key.indexOf(' ')
      const part1 = key.slice(0, spaceIndex)
      const part2 = key.slice(spaceIndex + 1)
      v.el.on(part1, part2, value)
    }
  }

四、模块化

  • 模块化就是把相对独立的代码从一大段代码里抽取成一个个短小精悍的模块
  • 每个模块之间相对独立,方便以后的维护和修改

ES6 的语法里引入了 import 和 export 就是用来实现模块化的

  • 可以使用 export default x 将一个变量默认导出给外部使用
  • 可以使用 import x from './xxx.js' 引用另一个模块导出的默认变量
  • 可以使用 import {x} from './xxx.js' 引用另一个模块导出的名为 x 的变量

*本文为鲲游北冥的原创文章,著作权归本人和饥人谷所有,转载务必注明来源

  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章           查看所有文章
加:2021-08-24 15:51:40  更:2021-08-24 15:52:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/17 22:35:21-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码