v-model与 mvvm 回顾

文章目录

    • 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方法会被调用,从而实现了发布 - 订阅模式下消息的传递和响应。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Unity学习笔记(七)使用状态机重构角色攻击

前言 本文为Udemy课程The Ultimate Guide to Creating an RPG Game in Unity学习笔记 攻击状态重构 首先我们重构攻击状态的动画 之前的动画&#xff0c;我们是使用状态(isAttacking)攻击次数(comboCounter)完成动画的过渡&#xff0c;这样虽然能完成功能&#xff0c;但是如…

Ubuntu20.04中安装ns-3.36及遇到的问题

一、安装虚拟机&#xff1a;VMware 17.5 参考教程&#xff1a;VMware17Pro虚拟机安装教程(超详细)-CSDN博客 博主&#xff1a;七维大脑 遇到的问题&#xff1a; Q1&#xff1a;安装ubuntu系统时&#xff0c;页面看不到”继续“选项&#xff0c;无法进行下一步 A&#xff…

iOS 逆向学习 - iOS Architecture Cocoa Touch Layer

iOS 逆向学习 - iOS Architecture Cocoa Touch Layer 一、Cocoa Touch Layer 简介二、Cocoa Touch Layer 的核心功能1. UIKit2. Event Handling&#xff08;事件处理&#xff09;3. Multitasking&#xff08;多任务处理&#xff09;4. Push Notifications&#xff08;推送通知&…

人大金仓实现主键自增.

使用数据库中自带的参数类型 serial 类型(相当于创建一个INT列), 或者bigserial(相当于创建一个BIGINT列. 示例sql: CREATE TABLE ord(id SERIAL,ord_no INT NOT NULL,ord_name VARCHAR(32),CONSTRAINT "ord_PKEY" PRIMARY KEY ("id"));插入时指定自增值…

React Router 向路由组件传state参数浏览器回退历史页面显示效果问题

昨天在看尚硅谷张天禹老师讲的 React教程p90&#xff0c;老师讲到 React路由的 replace模式和push模式&#xff0c;老师的演示效果与自己本地操作不太一样。 老师的效果&#xff1a;点击查看消息1&#xff0c;消息2&#xff0c;消息3 再点回退&#xff0c;可以依次查看到 消息…

selenium无法定位元素的几种解决方案

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 1、frame/iframe表单嵌套 WebDriver只能在一个页面上对元素识别与定位&#xff0c;对于frame/iframe表单内嵌的页面元素无法直接定位。 解决方法&#xff1a; d…

SSM-Spring-IOC/DI注解开发

目录 IOC/DI注解开发 1 注解开发定义bean 2 纯注解开发模式 步骤 Bean的作用范围 Bean生命周期 3 注解开发依赖注入 Autowired 注解实现按照名称注入 简单数据类型注入 注解读取properties配置文件 4 IOC/DI 注解开发管理第三方bean 4.1 步骤&#xff08;以管理第三…

深入探讨 Android 中的 AlarmManager:定时任务调度及优化实践

引言 在 Android 开发中&#xff0c;AlarmManager 是一个非常重要的系统服务&#xff0c;用于设置定时任务或者周期性任务。无论是设置一个闹钟&#xff0c;还是定时进行数据同步&#xff0c;AlarmManager 都是不可或缺的工具之一。然而&#xff0c;随着 Android 系统的不断演…

接口开发完后,个人对于接下来接口优化的一些思考

优化点 入参的合法性和长度范围&#xff0c;必填项的检查验证 因为没有入参&#xff0c;所以不需要考虑。 批量思想解决N1问题 // 假设要查询100个订单及其对应的用户信息 List<Order> orders orderMapper.selectList(new QueryWrapper<>().last("limit …

Redis内存碎片

什么是内存碎片? 你可以将内存碎片简单地理解为那些不可用的空闲内存。 举个例子&#xff1a;操作系统为你分配了 32 字节的连续内存空间&#xff0c;而你存储数据实际只需要使用 24 字节内存空间&#xff0c;那这多余出来的 8 字节内存空间如果后续没办法再被分配存储其他数…

小程序租赁系统开发的优势与应用前景分析

内容概要 小程序租赁系统是一种新兴的数字化解决方案&#xff0c;旨在为用户提供更加便捷与高效的租赁服务。它通常包括一系列功能&#xff0c;如在线浏览、即时预定、支付功能以及用户反馈机制。这些系统在使用上极为友好&#xff0c;让用户能够轻松选择所需的商品或服务&…

25年1月更新。Windows 上搭建 Python 开发环境:PyCharm 安装全攻略(文中有安装包不用官网下载)

python环境没有安装的可以点击这里先安装好python环境&#xff0c;python环境安装教程 安装 PyCharm IDE 获取 PyCharm PyCharm 提供两种主要版本——社区版&#xff08;免费&#xff09;和专业版&#xff08;付费&#xff09;。对于初学者和个人开发者而言&#xff0c;社区…

RedisTemplate执行lua脚本及Lua 脚本语言详解

使用RedisTemplate执行lua脚本 在开发中&#xff0c;我们经常需要与Redis数据库进行交互&#xff0c;而Redis是一个基于内存的高性能键值存储数据库&#xff0c;它支持多种数据结构&#xff0c;并提供了丰富的命令接口。在某些情况下&#xff0c;我们可能需要执行一些复杂的逻…

基于Python 的宠物管理系统(源码+部署)

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

stm32第一次烧录或者上电运行卡死问题分析

问题描述 单片机烧录代码&#xff08;刚上电&#xff09;无法立即运行&#xff0c;必须要复位一次或多次才能运行&#xff1b;跟踪调试会进入HardFault_Handler中断。 问题分析 烧录配置如下图&#xff0c;首先排除配置问题那么该问题就比较让人头大了&#xff0c;理论上&am…

ESP32-C3 AT WiFi AP 启 TCP Server 被动接收模式 + BLE 共存

TCP 被动接收模式&#xff0c;每次发的数据会先存到缓冲区&#xff0c;参见&#xff1a;ATCIPRECVTYPE 指令说明。 即每包数据不会实时报告 IPD 接收情况&#xff0c;如果需要查询缓冲区的数据&#xff0c;先用 ATCIPRECVLEN? 指令查询被动接收模式下套接字数据的长度 。获取…

【LeetCode Hot100 二分查找】搜索插入位置、搜索二维矩阵、搜索旋转排序数组、寻找两个正序数组的中位数

二分查找 搜索插入位置搜索二维矩阵在排序数组中查找元素的第一个和最后一个位置寻找旋转排序数组中的最小值搜索旋转排序数组寻找两个正序数组的中位数&#xff08;hard&#xff09; 搜索插入位置 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并…

ChatGPT 主流模型GPT-4/GPT-4o mini的参数规模是多大?

微软论文又把 OpenAI 的机密泄露了&#xff1f;&#xff1f;在论文中明晃晃写着&#xff1a; o1-preview 约 300B&#xff1b;o1-mini 约 100BGPT-4o 约 200B&#xff1b;GPT-4o-mini 约 8BClaude 3.5 Sonnet 2024-10-22 版本约 175B微软自己的 Phi-3-7B&#xff0c;这个不用约…

Docker 安装Elasticsearch搜索引擎 搜索优化 词库挂载 拼音分词 插件安装

介绍 允许用户快速索引和搜索大量的文本数据。通过使用倒排索引&#xff0c;它能够在海量数据中高效检索相关信息。提供灵活的查询语言&#xff0c;可以做全文搜索、模糊搜索、数据统计等&#xff0c;用来代替MYSQL的模糊搜索&#xff0c;MYSQL的模糊搜索不支持使用索引从而导…

Scala_【5】函数式编程

第五章 函数式编程函数和方法的区别函数声明函数参数可变参数参数默认值 函数至简原则匿名函数高阶函数函数作为值传递函数作为参数传递函数作为返回值 函数闭包&柯里化函数递归控制抽象惰性函数友情链接 函数式编程 面向对象编程 解决问题时&#xff0c;分解对象&#xff…