MVC和MVVM的区别

news2024/11/17 11:52:47

一、MVC

mvc:是一种代码架构设计模式,前端中的mvc最主要的作用就是将视图和数据模型进行分离

(1) 为什么需要 MVC

简单理解:也就是为什么需要将视图和数据模型进行分离

<select id="drinkSelect">
  <option value="coffee">coffee</option>
  <option value="milk">milk</option>
  <option value="juice">juice</option>
</select>
<p id="theColorOfDrink"></p>

<script type="text/javascript">
  document.getElementById('drinkSelect').onchange = function() {
    var color
    var colorOfDrink = {
      coffee: 'brown',
      milk: 'white',
      juice: 'orange'
    }
    color = colorOfDrink[this.value]
    document.getElementById('theColorOfDrink').innerHTML = color
  }
</script>

通过上面代码我们会发现视图的操作和数据以及逻辑的处理全部混淆在一起了,当前代码量小,并不会发现太大的问题,但是项目大,代码量多的时候,对于代码的维护会相对复杂,分离后具有如下优势

  • 维护性高 
  • 代码耦合性低 (相互联系较低)
  • 代码可复用

(2)如何设计MVC? 

mvc可以分为三个部分

  • 视图(View):用户界面。
  • 控制器(Controller):业务逻辑
  • 模型(Model):数据保存

V 视图层

页面结构

<select id="drinkSelect">
  <option value="coffee">coffee</option>
  <option value="milk">milk</option>
  <option value="juice">juice</option>
</select>
<p id="theColorOfDrink"></p>

dom 操作

showDrinkColor.view = {
  start: function() {
    // 获取select监听change事件
    document.getElementById('drinkSelect').onchange = this.onchange
  },
  onchange: function() {
    // 事件函数 做的逻辑 获取 变化后的数据传递给controller
    showDrinkColor.set(document.getElementById('drinkSelect').value)
  },
  update: function() {
    document.getElementById(
      'theColorOfDrink'
    ).innerHTML = showDrinkColor.model.getDrinkColor()
  }
}

M 数据层

数据和操作数据的逻辑:

showDrinkColor.model = {
  colorOfDrink: {
    coffee: 'brown',
    milk: 'white',
    juice: 'orange'
  },
  selectedDrink: null,
  setDrink: function(drinkName) {
    this.selectedDrink = this.colorOfDrink[this.selectedDrink]
      ? drinkName
      : null
    this.onchange()
  },
  onchange: function() {
    showDrinkColor.view.update()
  },
  getDrinkColor: function() {
    return this.selectedDrink
      ? this.colorOfDrink[this.selectedDrink]
      : 'white'
  }
}

C 控制层

视图和数据模型 进行关联

var showDrinkColor = {
  start: function() {
    // 给视图绑定事件
    this.view.start()
  },
  set: function(drinkName) {
    // 拿到视图传递过来的数据在调用数据模型的方法更新数据
    this.model.setDrink(drinkName)
  }
}
showDrinkColor.start()
  1. 视图发生变化触发 Controller,并且将数据传递给 Controller
  2. Controller 拿到更新的数据触发 model 并将更新的数据传递给 model
  3. model 拿到数据更新数据并且触发 view 视图更新

mvc通信方式流程

所有通信都是单向的。 

为了小伙伴们方便复制查看 合一个完整的

<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    mvc写法
    <select id="drinkSelect">
      <option value="coffee">coffee</option>
      <option value="milk">milk</option>
      <option value="juice">juice</option>
    </select>
    <p id="theColorOfDrink"></p>
    <script>
       var showDrinkColor = {
        start: function () {
          // 给视图绑定事件
          this.view.start();
        },
        set: function (drinkName) {
          // 拿到视图传递过来的数据在调用数据模型的方法更新数据
          this.model.setDrink(drinkName);
        },
      };

      showDrinkColor.view = {
        start: function () {
            console.log('监听了');
          // 获取select监听change事件
          document.getElementById("drinkSelect").onchange = this.onchange;
        },
        onchange: function () {
          // 事件函数 做的逻辑 获取 变化后的数据传递给controller
          showDrinkColor.set(document.getElementById("drinkSelect").value);
        },
        update: function () {
          document.getElementById("theColorOfDrink").innerHTML =
            showDrinkColor.model.getDrinkColor();
        },
      };

      showDrinkColor.model = {
        colorOfDrink: {
          coffee: "brown",
          milk: "white",
          juice: "orange",
        },
        selectedDrink: null,
        setDrink: function (drinkName) {
          this.selectedDrink = this.colorOfDrink[this.selectedDrink]
            ? drinkName
            : null;
          this.onchange();
        },
        onchange: function () {
          showDrinkColor.view.update();
        },
        getDrinkColor: function () {
          return this.selectedDrink
            ? this.colorOfDrink[this.selectedDrink]
            : "white";
        },
      };
      showDrinkColor.start();
    </script>
  </body>
</html>

 二、MVVM

MVVM 是 Model-View-ViewModel 的简写。它本质上就是 MVC 的改进版,整体和 mvc 差不多,最大的区别就是mvc 是单向的,而 mvvm 是双向的,并且是自动的,也就是数据发生变化自动同步视图,视图发生变化自动同步数据,同时解决了 mvc 中大量的 DOM 操作使页面渲染性能降低,加载速度变慢,影响用户体验。和当 Model 频繁发生变化,开发者需要主动更新到 View

在这里插入图片描述

    耦合低,是真的低,view 和 model 完全分离

    维护性高,易维护,上手快

    双向绑定:视图发生变化数据自动同步,数据发生变化视图也自动同步

    减少了 dom 的操作,可以更多的关注业务逻辑

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/184382.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

宕机后,如何避免 Redis 的数据丢失?

前言 如果有人问你&#xff1a;"你会把 Redis 用在什么业务场景下&#xff1f;" 我想你大概率会说&#xff1a;"我会把它当作缓存使用&#xff0c;因为它把后端数据库中的数据存储在内存中&#xff0c;然后直接从内存中读取数据&#xff0c;响应速度会非常快。…

Lua 文件I/O

Lua 文件I/O 参考至菜鸟教程。 Lua I/O 库用于读取和处理文件。分为简单模式&#xff08;和C一样&#xff09;、完全模式。 简单模式&#xff08;simple model&#xff09;拥有一个当前输入文件和一个当前输出文件&#xff0c;并且提供针对这些文件相关的操作。完全模式&#…

C++Primer13.6.2节练习

练习13.49&#xff1a; StrVec类的移动构造函数和移动赋值运算符 //移动构造函数 StrVec::StrVec(StrVec&& s)noexcept :elements(s.elements), first_free(s.first_free), cap(s.cap) {//令移后源对象进入状态-----对其运行析构函数是安全的s.elements s.first_fre…

关于网络编程

Socket套接字Socket API是网络编程最核心的部分。Socket套接字是由系统提供用于网络通信的技术&#xff0c;是基于TCP/IP协议的网络通信的基本操作单元。基于Socket套接字的网络程序开发就是网络编程。Socket API与传输层密切相关&#xff0c;由于传输层有UDP和TCP两种协议类型…

使用Idea中将单个java类打包成jar包

开工第一天&#xff0c;正在暗自爽&#xff0c;领导让帮个忙&#xff0c;给一个工具类打成jar包&#xff0c;供其他项目组使用&#xff0c;这就开始了尝试。 其实网上已经有好多人写过了&#xff0c;只是尝试了几篇&#xff0c;坑得不轻&#xff0c;自己做下笔记&#xff0c;留…

表格控件Aspose.Cells for .NET 授权须知

支持的平台 Aspose.Cells 可作为 .NET、Java、C 和 Python 的四种不同产品使用&#xff0c; .NET Framework.NET Standard 2.0Xamarin.AndroidXamarin.iOSXamarin.MacCOMMonoWindows Azure Aspose.Cells 下载&#xff08;qun&#xff1a;761297826&#xff09;https://www.ev…

python 高阶函数

传入函数 要理解“函数本身也可以作为参数传入”&#xff0c;可以从Python内建的map/reduce函数入手。 我们先看map。map()函数接收两个参数&#xff0c;一个是函数&#xff0c;一个是序列&#xff0c;map将传入的函数依次作用到序列的每个元素&#xff0c;并把结果作为新的l…

Java:基于注解的Spring使用【AOP容器】和事务管理

目录 第十五章 AOP前奏15.1 代理模式15.2 为什么需要代理【程序中】15.3 手动实现动态代理环境搭建15.4 手动实现动态代理关键步骤第十六章 Spring中AOP【重点】16.1 AspectJ框架【AOP框架】16.2 使用AspectJ步骤&#xff08;入门&#xff09;16.3 Spring中AOP概述16.4 Spring中…

AMQP 0-9-1 模型解释

官方文档链接&#xff1a;https://www.rabbitmq.com/tutorials/amqp-concepts.html 文章目录1. AMQP协议是什么2. AMQP模型2.1 工作过程2.2 深入理解3. 交换机3.1 默认交换机3.2 直连交换机3.3 扇形交换机3.4 主题交换机3.5 头交换机3.6 交换机小结4. Queue队列队列属性队列创建…

BM7 链表中环的入口结点

目录 描述 输入描述&#xff1a; 返回值描述&#xff1a; 示例1 示例2 示例3 思路&#xff1a; 代码 描述 给一个长度为n链表&#xff0c;若其中包含环&#xff0c;请找出该链表的环的入口结点&#xff0c;否则&#xff0c;返回null。 例如&#xff0c;输入{1,…

DW 2023年1月Free Excel 第九次打卡 Excel数据透视

第九章 Excel数据透视 数据下载地址与参考链接&#xff1a;https://d9ty988ekq.feishu.cn/docx/Wdqld1mVroyTJmxicTTcrfXYnDd 数据透视是Excel中个强大的数据处理和分析工具&#xff0c;能够快速实现数据的汇总与统计分析&#xff0c;本节重点讲解Excel数据透视的相关操作。 1…

NSSCTF Round#7 Team ez_rce和0o0讲解

强烈建议NSSCTF延长时间&#xff0c;大过年的逛亲戚回来就剩两个小时了。。。。 ez_rce <!-- A EZ RCE IN REALWORLD _ FROM CHINA.TW --> <!-- By 探姬 --> <?PHPif(!isset($_POST["action"]) && !isset($_POST["data"]))show_s…

MySQL8中jdbc的url设置

JDBC spring.datasource.urljdbc:mysql://${MYSQL_HOST:localhost}:3306/xxxx?sslModeREQUIRED&characterEncodingUTF-8&connectionTimeZoneGMT%2B8&forceConnectionTimeZoneToSessiontruesslMode:设置为REQUIRED表示必须启用ssl加密传输&#xff1b;characterEn…

svn客户端add无法添加上子文件夹及其子文件——解决办法

1、问题描述 svn客户端add文件夹后&#xff0c;无法添加上子文件夹及其子文件&#xff0c;需要先add最外层文件夹&#xff0c;再逐层add子文件夹&#xff0c;最后add最里层子文件夹中的文件&#xff0c;很影响add速度啊。现象如下图所示&#xff1a; 正常情况下&#xff0c;add…

公派访问学者申请优势有哪些?

人的一生&#xff0c;若从职业生涯论&#xff0c;无非为官、为学、为商三条路。为官者&#xff0c;出国访学一年半载&#xff0c;对仕途并无太大作用&#xff0c;并且在此期间有可能丧失国内提拔的大好机会;为学者&#xff0c;公派访问学者是对学术水平的认可&#xff0c;并且对…

vue.js 实现导入json解析成动态el-table树表格(接口文档功能)

一、需求描述&#xff1a;前段时间接到一个需求是做一个类似接口文档的显示功能&#xff0c;将一段json数据贴到里面就可以自动解析出json数据的每个字段的类型和层级关系&#xff0c;用element组件的树表格的形式展示&#xff0c;并且可以手动新增、修改和删除某个数据字段。二…

Vue路由和路由器简介

前言 路由(route)是vue中非常重要的技术&#xff0c;几乎每一个用vue所写的项目都会用到路由&#xff0c;它是一个vue的插件库&#xff0c;专门实现SPA应用 路由(route)的简介 说到路由&#xff0c;大多数人会想到路由器(router),可以这么说&#xff0c;路由器上的每一个口都…

Python类变量和实例变量

类变量&#xff08;类属性&#xff09;类变量指的是在类中&#xff0c;但在各个类方法外定义的变量。举个例子&#xff1a;class CLanguage : # 下面定义了2个类变量name "CSDN社区"add "http://csdn.net" # 下面定义了一个say实例方法 defsay(self, conte…

【Linux】进程信号的产生与捕捉、核心转储

目录 一、信号的引入 二、信号捕捉 三、核心转储 四、系统调用发送信号 五、软件条件产生信号 六、硬件异常产生信号 一、信号的引入 Linux信号本质是一种通知机制&#xff0c;用户 or 操作系统通过发送一定的信号&#xff0c;通知进程&#xff0c;某些事件已经发生&…

JavaWeb-MyBatis | Mapper代理开发及案例

本专栏主要是记录学习完JavaSE后学习JavaWeb部分的一些知识点总结以及遇到的一些问题等&#xff0c;如果刚开始学习Java的小伙伴可以点击下方连接查看专栏 本专栏地址&#xff1a;&#x1f525;JDBC Java入门篇&#xff1a; &#x1f525;Java基础学习篇 Java进阶学习篇&#x…