v-model与 mvvm 回顾

news2025/1/8 2:29:12

文章目录

    • v-model 与 mvvm
    • mvvm剖析
    • 发布-订阅,观察者模式

v-model 与 mvvm

  1. 概念理解
    • v-model
      • 定义:在Vue.js中,v-model是一个指令。它主要用于在表单元素(如inputtextareaselect等)和组件上创建双向数据绑定。这意味着当用户在表单元素中输入数据时,对应的Vue实例中的数据会自动更新,反之,当Vue实例中的数据发生变化时,表单元素显示的值也会随之改变。
      • 语法示例:在一个简单的input元素中,v - model的使用如下:
        <input v-model="message" type="text">
        
        在对应的Vue实例中:
        new Vue({
          el: '#app',
          data: {
            message: 'Hello Vue!'
          }
        });
        
        这里message是Vue实例中的数据属性,v-modelinput元素和message进行了双向绑定。
    • MVVM(Model - View - ViewModel)
      • 定义:MVVM是一种软件架构模式。它主要的目的是将用户界面(View)的开发与业务逻辑(Model)的处理分离开来,通过一个中间层(ViewModel)来进行数据的绑定和交互。在Vue.js中,Vue实例可以看作是ViewModel层。ViewModel负责从Model获取数据并将其提供给View展示,同时它也负责将View中的用户操作反馈给Model进行数据更新。
      • 架构示例
        • Model:可以是一个简单的JavaScript对象,例如:
          const user = {
            name: 'John',
            age: 30
          };
          
        • View:是HTML页面中的DOM元素,如:
          <div id="app">
            <p>{{ user.name }}</p>
            <input type="text" v - model="user.name">
          </div>
          
        • ViewModel:由Vue实例充当,像这样:
          new Vue({
            el: '#app',
            data: {
              user: user
            }
          });
          
  2. 区别
    • 层次不同
      • v-model是Vue框架中的一个具体指令,它主要关注的是在视图(View)层的表单元素和数据之间建立便捷的双向绑定关系。它是MVVM模式在Vue中实现数据双向绑定的一种具体手段。
      • MVVM是一种架构模式,它涉及到模型(Model)、视图(View)和视图模型(ViewModel)三个层次之间的关系和交互。它是一种更宏观的设计理念,用于组织和管理整个应用程序的结构,使得数据和视图能够有效地分离并且方便地进行交互。
    • 功能范围不同
      • v-model主要用于表单元素的双向数据绑定,功能比较聚焦。例如,它可以很方便地处理用户在inputtextareaselect等表单元素中的输入和数据更新。
      • MVVM涵盖的范围更广,它不仅包括数据绑定(像v - model所做的),还包括数据的获取、处理、存储(Model层),视图的渲染和事件处理(View层),以及中间的协调逻辑(ViewModel层)。例如,在一个复杂的应用中,ViewModel可能会从服务器获取数据(涉及Model),然后将数据处理成适合视图展示的格式,并且处理视图中的各种交互事件。
  3. 应用场景
    • v-model的应用场景
      • 表单处理:在用户注册、登录等表单场景中大量使用。例如,在一个用户注册表单中:
        <form>
          <input v - model="user.username" type="text" placeholder="Username">
          <input v - model="user.password" type="password" placeholder="Password">
          <button type="submit">Submit</button>
        </form>
        
        在Vue实例的data中定义user对象来存储用户输入的用户名和密码信息,方便后续的验证和提交操作。
      • 组件数据交互:当开发自定义组件并且需要在组件内部和外部进行数据双向传递时,v - model也非常有用。例如,创建一个自定义的计数器组件:
        <template>
          <div>
            <button @click="decrement">-</button>
            <span>{{ count }}</span>
            <button @click="increment">+</button>
          </div>
        </template>
        <script>
        export default {
          props: ['value'],
          data() {
            return {
              count: this.value
            };
          },
          methods: {
            increment() {
              this.count++;
              this.$emit('input', this.count);
            },
            decrement() {
              this.count--;
              this.$emit('input', this.count);
            }
          }
        };
        </script>
        
        使用组件时:
        <counter-component v-model="counter"></counter-component>
        
        这里通过v-model实现了组件内部count数据和外部counter数据的双向绑定。
    • MVVM的应用场景
      • 大型单页应用(SPA)开发:在构建复杂的单页应用时,MVVM模式可以很好地组织代码。例如,在一个电商单页应用中,Model层可以处理商品数据的获取(从服务器API获取商品列表、详情等)、用户数据(如用户信息、订单信息)的存储和更新。View层负责展示商品列表、商品详情、购物车界面等各种页面视图。ViewModel层则在中间协调数据和视图的交互,比如根据用户在视图中的操作(如添加商品到购物车)更新Model中的购物车数据,并及时更新视图中的购物车显示。
      • 数据驱动的UI开发:当需要根据数据的变化动态更新UI时,MVVM模式非常合适。比如在一个数据可视化应用中,Model层存储和管理数据(如从数据库或其他数据源获取的统计数据),ViewModel层对数据进行处理和转换,使其适合视图展示(如对数据进行排序、筛选、计算等),View层则根据ViewModel提供的数据进行图表绘制等操作。当数据发生变化时,通过MVVM的机制可以自动更新视图,保持数据和视图的一致性。

mvvm剖析

  1. MVVM模式的基本组成部分
    • Model(模型)
      • 定义:Model代表应用程序的数据和业务逻辑。它可以是简单的JavaScript对象,也可以是与后端服务器进行交互的复杂数据层。例如,在一个用户管理应用中,Model可能包含用户对象,其属性有用户名、密码、电子邮件等。这些数据可以从数据库中获取,并且Model可能包含一些方法用于验证用户数据的合法性,如验证密码强度、检查电子邮件格式等。
      • 示例
        const userModel = {
          data: {
            username: 'John',
            password: '123456',
            email: 'john@example.com'
          },
          validatePassword() {
            // 简单的密码验证逻辑
            return this.data.password.length >= 6;
          },
          validateEmail() {
            // 简单的电子邮件验证逻辑
            const emailRegex = /^[a-zA - Z0 - 9_.+-]+@[a-zA - Z0 - 9 -]+\.[a-zA - Z0 - 9-.]+$/;
            return emailRegex.test(this.data.email);
          }
        };
        
    • View(视图)
      • 定义:View是用户界面的呈现部分,通常是由HTML、CSS和JavaScript(用于交互)构建的。它负责将数据展示给用户,并且接收用户的操作事件。在网页应用中,View就是用户在浏览器中看到的页面内容。例如,一个用户登录页面的View包括输入用户名和密码的表单元素,以及登录按钮等。
      • 示例
        <div id="login - view">
          <h1>Login</h1>
          <form>
            <input type="text" id="username - input" placeholder="Username">
            <input type="password" id="password - input" placeholder="Password">
            <button id="login - button">Login</button>
          </form>
        </div>
        
    • ViewModel(视图模型)
      • 定义:ViewModel是连接Model和View的桥梁。它监听Model数据的变化,并将这些变化反映到View上;同时,它也监听View中的用户操作事件,并将这些事件转换为对Model的操作。ViewModel通常会暴露一些可观察的数据属性和方法,供View进行绑定和调用。在Vue.js中,Vue实例就充当了ViewModel的角色。
      • 示例:假设我们使用Vue.js来实现上述登录页面的ViewModel部分。
        new Vue({
          el: '#login - view',
          data: {
            username: '',
            password: ''
          },
          methods: {
            login() {
              // 这里可以调用Model的验证方法并进行登录操作
              const userModel = {
                data: {
                  username: this.username,
                  password: this.password
                },
                validatePassword() {
                  // 简单的密码验证逻辑
                  return this.data.password.length >= 6;
                },
                validateEmail() {
                  // 简单的电子邮件验证逻辑
                  const emailRegex = /^[a-zA - Z0 - 9_.+-]+@[a-zA - Z0 - 9 -]+\.[a-zA - Z0 - 9-.]+$/;
                  return emailRegex.test(this.data.email);
                }
              };
              if (userModel.validatePassword()) {
                console.log('Login successful');
              } else {
                console.log('Invalid password');
              }
            }
          }
        });
        
  2. MVVM的工作流程原理
    • 数据绑定(从Model到View)
      • 单向数据绑定启动:当应用程序启动时,ViewModel会获取Model中的数据,并将其转换为可以被View理解和使用的格式。例如,在Vue.js中,通过data属性将Model中的数据暴露给View。在上述登录页面的例子中,usernamepassword数据属性在ViewModel(Vue实例)的data中定义,它们可以被View中的表单元素通过插值语法(如{{ username }})或者指令(如v - model)进行绑定。
      • 数据更新传播:当Model中的数据发生变化时,ViewModel会检测到这种变化。这可能是因为从服务器获取了新的数据,或者是应用程序内部的逻辑导致数据更新。ViewModel会将新的数据更新到View上。在Vue.js中,这种更新是自动的,通过其响应式系统实现。例如,如果Model中的用户信息因为用户编辑而更新,ViewModel会自动更新View中显示用户信息的部分,如更新用户名显示的p标签中的内容。
    • 事件绑定(从View到Model)
      • 事件监听建立:ViewModel会在View中设置事件监听器。在登录页面的例子中,ViewModel(Vue实例)通过v - on(缩写为@)指令监听login - buttonclick事件。当用户点击登录按钮时,对应的login方法在ViewModel中被调用。
      • 事件处理与Model更新:当View中的事件被触发后,ViewModel中的方法会执行相应的业务逻辑。这些业务逻辑可能会涉及到对Model数据的更新。例如,在登录方法login中,会获取View中用户输入的用户名和密码(通过this.usernamethis.password),并将其传递给Model进行验证。如果验证成功,可能会进一步更新Model中的用户登录状态等数据,同时也可能会触发后续的操作,如导航到用户主页等。
    • 双向数据绑定(结合数据绑定和事件绑定)
      • 指令实现双向绑定:在一些情况下,如表单元素的输入,需要实现双向数据绑定。在Vue.js中,v - model指令就实现了这种功能。以input元素为例,v - model在内部实际上是结合了数据绑定和事件绑定。它将input元素的value属性与ViewModel中的数据属性进行绑定(数据绑定),同时监听input元素的input事件(事件绑定)。
      • 工作机制说明:当用户在input元素中输入内容时,input事件被触发。v - model指令会获取新输入的值,并更新ViewModel中的数据属性。然后,由于数据绑定的存在,ViewModel会将更新后的数据传播到View中的其他部分,实现了数据的双向流动。例如,在一个实时搜索功能的应用中,用户在搜索框(input元素)中输入关键词,v - model会更新ViewModel中的搜索关键词数据,ViewModel可以根据这个新的数据向服务器发送搜索请求,同时更新View中显示搜索结果的部分。

发布-订阅,观察者模式

  1. 观察者模式(Observer Pattern)
    • 概念
      • 观察者模式是一种软件设计模式。在这种模式中有两个主要角色:被观察者(Subject)和观察者(Observer)。被观察者维护一个观察者列表,当被观察者的状态发生变化时,它会通知所有注册的观察者。观察者定义了一个更新接口,当接收到被观察者的通知时,会执行这个更新接口来做出响应。
    • 在Vue中的体现
      • 响应式数据:Vue的响应式数据系统可以看作是观察者模式的应用。以Vue实例中的data属性为例,每个被定义在data中的数据属性都是一个被观察者。当这些数据属性的值发生变化时,它们会通知与之关联的观察者,也就是使用这些数据属性的DOM元素(通过插值表达式、指令等方式关联)。
      • 实现细节:Vue使用Object.defineProperty(在ES5环境)或者Proxy(在ES6环境)来进行数据劫持。例如,当使用Object.defineProperty时,对于data中的每一个属性,会定义getset方法。get方法用于获取属性值,在这个过程中可以进行依赖收集,也就是记录哪些组件或者DOM元素(观察者)使用了这个属性。set方法用于设置属性值,当属性值被修改时,会触发set操作,此时会遍历之前收集的依赖(观察者)并通知它们进行更新。
      • 示例代码
        function defineReactive(obj, key, value) {
          let dep = new Dep();
          Object.defineProperty(obj, key, {
            get: function () {
              if (Dep.target) {
                dep.addSub(Dep.target);
              }
              return value;
            },
            set: function (newValue) {
              if (value === newValue) return;
              value = newValue;
              dep.notify();
            }
          });
        }
        
        这里Dep是一个依赖管理类,用于收集和通知观察者。defineReactive函数通过Object.defineProperty来实现数据的响应式。当属性被访问(get)时,收集依赖;当属性被修改(set)时,通知依赖进行更新。
  2. 发布 - 订阅模式(Publish - Subscribe Pattern)
    • 概念
      • 发布 - 订阅模式包含三个主要角色:发布者(Publisher)、订阅者(Subscriber)和消息中心(Broker)。发布者将消息发送到消息中心,而不是直接发送给订阅者。订阅者向消息中心订阅感兴趣的消息类型。当消息中心收到发布者发送的消息后,会将消息转发给所有订阅了该消息类型的订阅者。
    • 与观察者模式的区别
      • 在观察者模式中,被观察者和观察者是紧耦合的,被观察者需要直接维护观察者列表并通知它们。而在发布 - 订阅模式中,发布者和订阅者是通过消息中心解耦的,发布者不需要知道订阅者的存在,订阅者也不需要知道发布者的存在,它们只和消息中心交互。
    • 在Vue中的体现
      • 事件系统:Vue的事件系统可以看作是发布 - 订阅模式的一种应用。$on方法用于订阅事件,$emit方法用于发布事件。例如,在一个组件中,当一个按钮被点击时,可以通过$emit发布一个自定义事件,而其他组件可以通过$on订阅这个事件来做出响应。
      • 示例代码
        • 发布事件(在子组件中)
          export default {
            methods: {
              handleClick() {
                this.$emit('custom - event', 'Hello, World!');
              }
            }
          };
          
        • 订阅事件(在父组件中)
          new Vue({
            el: '#app',
            methods: {
              handleCustomEvent(message) {
                console.log(message);
              }
            },
            mounted() {
              this.$on('custom - event', this.handleCustomEvent);
            }
          });
          
        • 这里子组件通过$emit发布了一个名为custom - event的事件,并传递了一个消息。父组件通过$on订阅了这个事件,当事件被发布时,父组件的handleCustomEvent方法会被调用,从而实现了发布 - 订阅模式下消息的传递和响应。

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

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

相关文章

OpenGL材质系统和贴图纹理

上一篇文章当中笔者为大家介绍了风氏光照模型&#xff0c;相信大家也发现了光照着色器当中有设置有很多控制光照强度的参数&#xff0c;而所谓的材质系统就是我们可以人为的去调节这些参数&#xff0c;让一个物体的反光效果能够更加接近我们现实生活当中的一些物体。 材质系统…

【mybatis】Mybatis整体架构解析

从本篇开始我们开始学习mybatis的系列源码&#xff0c;主要的主题可能就是四个方面 从整体把握mybatis系统架构通过一个查询SQL 源码解析核心流程mybatis的缓存机制-源码级别mybatis的插件机制-源码级别spring是如何整合的mybatis框架的 1.整体架构 上述是mybatis的源码&…

stm32 智能语音电梯系统

做了个stm32智能语音控制的电梯模型&#xff0c;总结一下功能&#xff0c;源码用ST的HAL库写的&#xff0c;整体流程分明。 实物图 这个是整个板子的图片&#xff0c;逻辑其实并不复杂&#xff0c;只是功能比较多&#xff0c;在我看来都是一些冗余的功能&#xff0c;但也可能是…

Git 部署

参考&#xff1a;手把手教你入门Git — Git使用指南&#xff08;Linux&#xff09; 需要说明的是&#xff1a; 1、服务器linux系统中一般使用master分支&#xff0c;但github现在流行的是main分支&#xff1b; 解决方案是修改master分支位main分支 git branch -m master mai…

【业务场景】sql server从Windows迁移到Linux

目录 1.背景 2.Linux安装sql server 3.服务器不开端口的问题 4.数据库导入导出问题 1.背景 博主在24年年底接手运维了一个政府的老系统&#xff0c;整个应用和数据库单点部署在一台Windows Server服务器上&#xff0c;数据库选型是经典的老项目标配——sql server。随着近…

《Vue3实战教程》35:Vue3测试

如果您有疑问&#xff0c;请观看视频教程《Vue3实战教程》 测试​ 为什么需要测试​ 自动化测试能够预防无意引入的 bug&#xff0c;并鼓励开发者将应用分解为可测试、可维护的函数、模块、类和组件。这能够帮助你和你的团队更快速、自信地构建复杂的 Vue 应用。与任何应用一…

字玩FontPlayer开发笔记6 Tauri2设置菜单

字玩FontPlayer开发笔记6 Tauri2设置菜单 字玩FontPlayer是笔者开源的一款字体设计工具&#xff0c;使用Vue3 ElementUI开发&#xff0c;源代码&#xff1a; github: https://github.com/HiToysMaker/fontplayer gitee: https://gitee.com/toysmaker/fontplayer 笔记 字玩目…

我用AI学Android Jetpack Compose之开篇

最近突发奇想&#xff0c;想学一下Jetpack Compose&#xff0c;打算用Ai学&#xff0c;学最新的技术应该要到官网学&#xff0c;不过Compose已经出来一段时间了&#xff0c;Ai肯定学过了&#xff0c;用Ai来学&#xff0c;应该问题不大&#xff0c;学习过程记录下来&#xff0c;…

Zookeeper是如何保证事务的顺序一致性的?

大家好&#xff0c;我是锋哥。今天分享关于【Zookeeper是如何保证事务的顺序一致性的?】面试题。希望对大家有帮助&#xff1b; Zookeeper是如何保证事务的顺序一致性的? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Zookeeper 通过多个机制来保证事务的顺序一…

机器人手眼标定

机器人手眼标定 一、机器人手眼标定1. 眼在手上标定基本原理2. 眼在手外标定基本原理 二、眼在手外标定实验三、标定精度分析 一、机器人手眼标定 要实现由图像目标点到实际物体上抓取点之间的坐标转换&#xff0c;就必须拥有准确的相机内外参信息。其中内参是相机内部的基本参…

数据挖掘——聚类

数据挖掘——聚类 聚类K-meansKNN VS K-meansK-Nearest Neighbors (KNN)K-means K中心算法PAM算法 K-modes算法——解决数据敏感的问题KMeans算法 ——解决初始点选择问题K-中心点层次方法AGNES算法——最小距离单链接全链接平均链接 聚类评估K均值和K中心点的优缺点层次化聚类…

web实操9——session

概念 数据保存在服务器HttpSession对象里。 session也是域对象&#xff0c;有setAttribute和getAttribute方法 快速入门 代码 获取session和塞入数据&#xff1a; 获取session获取数据&#xff1a; 请求存储&#xff1a; 请求获取&#xff1a; 数据正常打印&#xff1a…

GPT系统重大升级,开创国内先河:o1支持图片识别功能正式上线

文章目录 零、前言一、授权码登录体验优化&#xff1a;一步直达聊天界面二、全新“项目”功能&#xff1a;让工作更有条理三、语音功能升级&#xff1a;全新交互体验四、o1支持图片识别五、总结 零、前言 我是虚竹哥&#xff0c;目标是带十万人玩转ChatGPT。 亲爱的用户&…

unity 播放 序列帧图片 动画

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、方法一&#xff1a;代码控制播放序列帧1、设置图片属性2、创建Image组件3、简单的代码控制4、挂载代码并赋值 二、方法二&#xff1a;直接使用1.Image上添加…

VisionPro软件Image Stitch拼接算法

2D图像拼接的3种情景 1.一只相机取像位置固定&#xff0c;或者多只相机固定位置拍图&#xff0c;硬拷贝拼图&#xff0c;采用CopyRegion工具实现 2.一只或多只相机在多个位置拍照&#xff0c;相机视野互相重叠&#xff0c;基于Patmax特征定位后&#xff0c;无缝 拼图&#xff…

【大模型】7 天 AI 大模型学习

今天终于来到大模型学习的实战课了&#xff08;虽然前面跳了2天的课&#xff09;&#xff0c;今天我们会一起学习 Llama 模型的运行、部署、微调 ~ 一、Llama 介绍 Llama 模型官网&#xff1a;官网 Llama 论文&#xff1a;论文 Llama 代码&#xff1a;代码 理念&#xff1a;Th…

小程序学习08—— 系统参数获取和navBar组件样式动态设置

一 系统信息的概念 uni-app提供了异步(uni.getSystemInfo)和同步(uni.getSystemInfoSync)的2个API获取系统信息。 success 返回参数说明&#xff1a; 参数分类说明statusBarHeight手机状态栏的高度system操作系统名称及版本。。。 二 自定义navbar 2.1 获取系统参数 代码展示…

STM32的LED点亮教程:使用HAL库与Proteus仿真

学习目标&#xff1a;掌握使用STM32 HAL库点亮LED灯&#xff0c;并通过Proteus进行仿真验证&#xff01; 建立HAL库标准工程 1.新建工程文件夹 新建工程文件夹建议路径尽量为中文。建立文件夹的目的为了更好分类去管理项目工程中需要的各类工程文件。 首先需要在某个位置建立工…

密码学原理技术-第十一章-Hash Functions

文章目录 总结Why we need hash functionsDigital Signature with a Hash FunctionBasic Protocol for Digital Signatures with a Hash FunctionPrincipal input–output behavior of hash functions Security propertiesThe three security requirements of hash functionsWh…

【AI大模型系列】AI Agent与LangChain框架介绍(七)

目录 一、什么是AI Agent 二、什么是LangChain 三、LangChain的重要模块 3.1 Model I/O&#xff08;模块输入输出&#xff09; 3.2 Retrieval&#xff08;检索&#xff09; 3.3 Chains&#xff08;链式调用&#xff09; 3.4 Agents 3.5 Memory&#xff08;记忆&#xff…