html理解MVC模型与MVVM模型底层实现

2023-11-20

一、MVC模型的底层实现

1.1 相关代码

<!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>MVC模型</title>
    <style></style>
  </head>
  <body>
    <div id="view"></div>
    <div id="btn"></div>

    <script type="text/javascript">

      //MVC模型分为下面三部分:
      //1.model(模型层)模拟后端提供来的数据
        const data = {
          name:'小明'
        }

      //2.view(视图层)将数据在页面渲染的操作
        function showName(){
          //方法定义获取dom中的id为view的node节点,并通过innerHTML来动态写入html标签。
          document.getElementById('view').innerHTML = `<h3>${data.name}</h3>`
          document.getElementById('btn').innerHTML = `<button οnclick="switchName()">切换名字</button>`
        }
        //在页面调用showName()方法
        showName()

      //3.controller(控制台层)
      // 通过视图层点击按钮,对model模型层的数据进行修改并且调用showName(),方法刷新页面(需要手动刷新DOM页面才能看到修改的数据)
        function switchName(){
          if(data.name == '小红'){
            data.name = '小明'
          }else{
            data.name = '小红'
          }
          showName()
        }
    </script>
  </body>
</html>

1.2 运行截图

在这里插入图片描述

1.3 遇到的坑

问题1:$ { }与{{ }}的区别?
回答1:$ { }是原生JS中,模板字符串中,某变量对应的值,{{ }}是vue中,用来调用组件属性某变量对应的值。

  • $ { }:在js中的模板字符串,而 $ {A}是代表变量A的值插入进此模板字符串中,通常模板字符串与${ }搭配使用。
  • {{ }}:是vue的语法特性,通常是用来在html中插入组件属性,通常为data函数中的数据。

二、MVVM模型的底层实现

2.1 VUE2

2.1.1 Object.defineProperty()的简单应用

首先介绍vue2的Object.defineProperty()的应用,因为MVVM模型在视图层与模型层中有一个视图模型,而VUE2中视图模型层的响应式数据双向绑定,是通过Object.defineProperty()实现的,所以先看看Object.defineProperty()的相关代码。

	 const data ={
       name:'小蓝'
     }

     //Object.defineProperty() 表示数据劫持
     //它是Object类的defineProperty
     // 第一个参数为劫持对象,第二个参数为劫持对象中的属性名称,第三个定义get和set的方法
     Object.defineProperty(data,'name',{
       // 访问劫持数据时触发
       get(){
         console.log('get====')
         return '我是从劫持数据中get所返回的值'
       },
       //需要给挟持数据进行赋值的时候触发
       set(getNewValue){
         console.log('set====',getNewValue)
       }
     })

     //给模型层的数据赋值时,触发数据劫持中的set方法,阻止直接赋值并把想赋的值传到set的getNewValue中
     data.name = '想要传数据'
     //视图层需要读取model的值时,触发数据劫持中的get方法,所打印出来的值是get方法中返回的值。
     console.log('data.name',data.name)

2.1.2 基于Object.defineProperty()的MVVM模型实现(vue2.0)

2.1.2.1 VUE2的MVVM模型底层实现相关代码

<!DOCTYPE html>
<html>
  <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>MVVM模型</title>
    <style></style>
  </head>
  <body>
    <div id="view"></div>

    <script type="text/javascript"> 
      //基于Object.defineProperty()的MVVM模型实现(vue2.0)
      //1.model(模型层)后端传过来的数据
      const data = {
        name:'小红'
      }

      //2.view(视图层)数据渲染的操作
      function showName(){
        //下方定义一个input框,表单元素,修改视图层的数据通知视图模型层进行数据劫持进行数据的双向响应式绑定
        document.getElementById('view').innerHTML = `<h3>${data.name}</h3>
        <input type="text" value="${data.name}" οnchange='changeValue(this)'>
        `
      }

      showName()

      //3.viewModel(视图模型层)介于视图与模型之间的桥梁,实现数据的双向绑定
      let insideValue = data.name
      Object.defineProperty(data,'name',{
        //访问data.name中的值执行get
        get(){
          console.log('get')
          return insideValue
        },
        //修改data.name中的值执行set
        set(newValue){
          console.log('set')
          insideValue = newValue
          //调用以下showName()方法中,由于在其中innerHTML中获取了两次模型层中的data.name,所以会进行两次数据劫持的get操作
          showName()
        }
      })

      //定义input修改它的值时,对model模型进行赋值并触发视图模型层的数据劫持
      function changeValue(setValue){
        console.log('输入框中的值为',setValue.value)
        data.name = setValue.value
      }
    </script>
  </body>
</html>

2.1.2.2 VUE2的MVVM模型底层实现运行截图

在这里插入图片描述

2.1.3 Object.defineProperty()的缺点

vue 2中使用上述数据劫持时会有个问题,就是当对象的属性新增与数组的长度,或是下标添加的元素的时候,会监听不到此对象。
因此vue2也有相应的解决方案,在vue2中会当修改对象或者数组的时候,会对底层进行封装,对原数据原型对象进行重写实现响应式。方法如下:

  • 对象:
  1. 对象新增:this.set(对象,‘属性’,值)
  2. 对象合并:Object.assign({},对象,新对象)
  3. 对象的浅拷贝:…对象,{‘属性’:值}
  • 数组:
  1. 数组新增:this.set(数组,下标,值)
  2. 数组的增删:push(),pop(),shift(),unshift(),splice(),sort(),reverse()

2.2 VUE3

2.2.1 基于proxy的MVVM模型实现(vue3.0)

proxy是个构造函数,从ES6中提出来的,为了解决vue2的Object.defineProperty()的缺陷。通过proxy确定第一个参数确定劫持对象,在里面get与set中再确定进行监听数据的对象以及它的属性名。

let vThree = new Proxy(data,{
   insideItem是监听数据对象,indsideIndex是监听数据对象的属性名
    get(insideItem,insideIndex){
      console.log('get===')
      return insideItem[insideIndex]
    },

    set(insideItem,insideIndex,newValue){
      console.log('set===')
      insideItem[insideIndex] = newValue
      showName()
    }
  })
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

html理解MVC模型与MVVM模型底层实现 的相关文章

  • 除了text/css之外还有其他样式类型吗? [复制]

    这个问题在这里已经有答案了 可能的重复 style type text css 还有什么 https stackoverflow com questions 6077905 style type text css what else is
  • 使用加权概率和值查找数组中的项目

    上周我正在做的一个简单程序遇到了一些问题 这里有人帮助了我 现在我遇到了另一个问题 我目前有这个代码 var findItem function desiredItem var items item rusty nail probabili
  • Ajax - 下载前获取文件大小

    基本上 我想弄清楚是否应该使用 AJAX 下载文件 具体取决于文件大小有多大 我想这个问题也可以改写为 如何仅获取ajax请求的标头 EDIT ultima rat0 https stackoverflow com users 239962
  • 在电子邮件中设置 html 样式

    我正在为有能力的客户发送 HTML 版本的电子邮件 现在这不是几乎全部吗 我担心的是如何设计它 我使用内联CSS吗 我可以在 html 中包含样式表吗 html 是否以 or 我可以阅读这方面的标准吗 我在造型方面能走多远 我有边框半径 背
  • 锁定 contenteditable="true" div 中的元素

    我有一个用于用户输入的 contenteditable div 当单击按钮时 它会显示替换某些单词的选项 首先 它删除所有 html 并创建可以替换单词的 span 元素 这些词的标记不同 我面临一些问题 当直接在跨度之前或之后单击并键入文
  • Javascript 中繁重计算的最佳实践?

    我正在处理客户端脚本 需要进行繁重的计算 例如将大量对象推送到数组中 这会导致 JavaScript 停止响应并且浏览器挂起并发出警报 是否有任何最佳实践或设计模式来处理这些计算 我搜索并找到许多不同的方法来处理这些情况 但解决方案很难实现
  • 在 mdn web 文档中 Element.querySelector 方法说它应该是后代,但示例显示不然

    我正在从 MDN 网络文档学习 JavaScript 我刚刚在学习Element querySelector method 据记载 它返回第一个元素 该元素是调用它的元素的后代 并且与指定的选择器组匹配 但有一个例子与这个事实相矛盾 var
  • 为什么在 Javascript 中添加两位小数会产生错误的结果? [复制]

    这个问题在这里已经有答案了 可能的重复 JavaScript 的数学有问题吗 https stackoverflow com questions 588004 is javascripts math broken 为什么 JS 搞砸了这个简
  • 如果 jQuery 验证失败,JSLint 有什么用?

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 返回 Web 浏览器中 HtmlElement 的所有属性

    我需要从我的网络浏览器获取所有属性 当前 我正在使用 GetAttribute 但这样 我需要知道属性的名称 想象一下我不知道我的网络浏览器中有什么 我的 C 代码 StringWriter strWriter new StringWrit
  • 检测“文件下载”弹出窗口何时关闭

    我有一个网页 用 JSF 制作 其中一些链接允许用户获取 PDF 文件 当用户点击这样的链接时 会显示一个等待弹出窗口 它是一个模式面板 因为 PDF 的生成可能很长 并且一旦创建文件 IE 就会显示 文件下载 弹出窗口 建议 打开 保存
  • 为什么 justify-content 不以我的 div 为中心?

    我试图将两个 div 水平居中放在爸爸 div 内 爸爸 div 设置为flex direction column因为我希望子 div 一个在另一个之下 但位于页面的中心 justify content center 应该做但不起作用 我终
  • 玩笑测试因 refs 和 Form 失败

    我有一个搜索栏组件 如下所示 render const onChangeTextInput this props return
  • 使用 javascript 检测 CSP 违规

    是否可以使用 JavaScript 检测内容安全策略违规 我的 CSP 工作并发送其报告 我看到一些 url 被注入 可能是通过浏览器插件注入的 我想向用户显示一个提示 即某些插件尝试修改页面 我能否以某种方式检测与 javascript
  • Ember JS 过渡到嵌套路由,其中​​所有路由都是视图中的动态段

    我们正在使用 EmberJS 编写一个应用程序 然而 我们对这个框架仍然陌生 我们很难解决一些看似简单的问题 模型非常简单 有 3 个模型 Queue Task 和 Image 我们对所有路由使用动态 URI 段 并且这些模型的路由嵌套在以
  • 为什么 JavaScript 原型属性在新对象上未定义?

    我对 JavaScript 原型概念还很陌生 考虑以下代码 var x function func x prototype log function console log 1 var b new x 据我了解 b log 应该返回 1 因
  • javascript 中的独立括号[重复]

    这个问题在这里已经有答案了 可能的重复 JavaScript 为什么使用匿名函数包装器 https stackoverflow com questions 1643321 javascript why the anonymous funct
  • JavaScript 使用多少位来表示数字?

    JavaScript 使用多少位来表示数字 一般JS实现使用64位双精度浮点数 对 32 位整数执行按位运算
  • 使用 JavaScript 将图像上传到 Web 服务

    我需要从 javascript 将图像上传到网络服务 我必须发送一个 json 字符串和一个文件 图像 在java中我们有MultipartEntity 我在java中有以下代码 HttpPost post new HttpPost aWe
  • 将 JS 文件导入 Typescript

    我正在考虑转向 Typescript 目前正在考虑慢慢地 如果可能的话 逐个文件地执行此操作 现在我目前拥有的系统是用 Webpack 构建的 我想继续这个来构建我的整个包 我有一个用于定义的 d ts 文件 但我需要继续导入当前引发错误的

随机推荐

  • numpy索引与切片

    一 整数索引 作用 要获取数组的单个元素 指定元素的索引即可 例子 x np array 1 2 3 4 5 6 7 8 print x 2 3 x np array 11 12 13 14 15 16 17 18 19 20 21 22
  • listview item设置点击跳转_Flutter之路由及页面跳转与返回

    1 路由跳转到页面思路 设计三个按钮 然后三个点击事件 利用Navigator of context push MaterialPageRoute builder context gt page 进行跳转新页面2 页面折回到路由在跳转的页面
  • 小程序v-for与key值使用

    小程序中的v for和key与Vue中的用法基本相同 v for用于循环渲染列表 key用于给每个循环项分配一个唯一的标识 使用v for时 通常建议使用wx for代替 例如
  • SQL Server 中给字段设置默认值的方式

    1 在创建表的时候创建默认值 if object id T U is not null drop table T GO create table T ID int Name varchar 20 LoginTime datetime def
  • RecyclerView应用 —— 好友列表实现

    实现的效果类似于QQ好友列表 点击可展开 再次点击收起 两个Item的布局都很简单 这里就不给布局代码了 值得一提的是 RecyclerView本身并没有ListView那样的点击效果 想要类似效果可以为Item的根布局写个Selector
  • JS混淆加密的代码如何解密

    科普简介 混淆是指将 JavaScript 代码变得难以理解的过程 这可以通过更改变量名 函数名和类名 以及将代码压缩到一行来实现 混淆的主要目的是使代码难以被盗用 并保护代码的知识产权 功能作用与常用的解决方案 混淆后的代码很难阅读 但是
  • Maven进阶-配置仓库

    1 1maven介绍 Maven是一个项目管理和综合工具 Maven提供了开发人员构建一个完整的生命周期框架 开发团队可以自动完成项目的基础工具建设 Maven使用标准的目录结构和默认构建生命周期 主要服务于基于Java平台的项目构建 依赖
  • Linux系统如何看目录属于哪个磁盘分区

    Linux是先有目录 再有磁盘分区 df h 目录 例如 没有挂载磁盘的目录 显示在系统盘 root iZ2ze57v3n0zma46zqiq8nZ sh 1 5 5 df h alidata Filesystem Size Used Av
  • Unity使用spine动画

    Unity使用spine动画 在 Unity 中 常常使用 Spine 来制作一些动画 引擎本身并不能直接播放 Spine 动画 需要额外导入一个 RunTime 插件库才能支持 官网插件导入 当然 也可以到 Spine 官网关于 Unit
  • 机器学习原理(1)集成学习基本方法

    一 什么是集成学习 集成学习 ensemble learning 通过将多个学习器进行组合来完成学习任务 下图显示集成学习的一般结构 取自周志华老师的西瓜书 个体学习器通常由一种现有的学习算法从训练数据产生 例如决策树 C4 5 CART
  • C语言之——自定义数据类型

    目录 前言 什么是自定义数据类型 一 自定义数据类型之 数据类型命名 1 深入应用typedef 二 自定义数据类型之 结构体类型命名 1 深入理解struct结构体 三 自定义数据类型之 联合体类型命名 1 union与struct的区别
  • FreeRTOS多任务调度器基础

    Cortex M4中SysTick调度器核心 Cortex M4中的中断管理 Cortex M4中影子栈指针 Cortex M4中SVC和PendSV异常 1 Cortex M4中SysTick调度器核心 systick每一次中断都会触发内
  • c语言—指针非常全面、详细

    目录 一 初步认识指针 一级 二 数组指针 1 一维数组与指针 2 二维数组与指针 三 函数指针 四 指针数组 2 函数指针数组 五 指针函数 六 二级 多级 指针 七 指针定义的归纳 一 初步认识指针 一级 1 指针变量 指针变量是一个特
  • c++优先队列简介及例题:5.4.1 围栏修复

    优先队列 其实就是个队列 只不过里面的元素会被自动按一定的顺序来排列 可以是递增顺序 也可以是递减顺序 写法如下 头文件 include
  • 020 - STM32学习笔记 - Fatfs文件系统(二) - 移植与测试

    020 STM32学习笔记 Fatfs文件系统 二 移植与测试 上节学习了FatFs文件系统的相关知识 这节内容继续学习在STM32上如何移植FatFs文件系统 并且实现文件的创建 读 写与删除等功能 各位看官觉得还行的话点点赞 收藏一下呗
  • FastDFS-01-单机和集群搭建

    我是码赛客1024 本节我们一起搭建FastDFS 一 介绍 FastDFS是一个开源的轻量级分布式文件系统 它对文件进行管理 功能包括 文件存储 文件同步 文件访问 文件上传 文件下载 等 解决了大容量存储和负载均衡的问题 特别适合以文件
  • 对象创建的几个步骤

    对象创建的几个步骤 一 先把要创建的对象的类信息加载进内存 二 在内存开辟空间 1 如果内存是规整的 则使用指针碰撞 2 如果不规整 则会维护一个空闲列表 内存是否规整根据具体的垃圾回收算法来决定 三 开辟空间需要解决并发问题 在堆中创建对
  • shell脚本一键安装JDK及配置环境变量

    这是我学了半天shell写出来的 不适合大神看 为什么我要写这样安装JDK并配置环境变量的脚本呢 因为我和linux打交道还是比较多的 然而每次都要安装JDK 配置环境变量 这样的事情对于刚接触linux的人来说是很乐意做的 但是接触多了
  • 浏览器请求队列机制-请求为什么会阻塞

    前言 最近遇到一个问题 我1个站点链接2个后端服务 但1个后端服务有问题 导致访问超时 但请求接口都是分开的 自认为一个服务站点请求超时 不会影响到另外一个请求的 但不是 全部请求都发不出去 为什么呢 是不是浏览器有请求机制管理 正常情况前
  • html理解MVC模型与MVVM模型底层实现

    一 MVC模型的底层实现 1 1 相关代码 div div