当前位置: 首页 > article >正文

Vue 双向数据绑定的原理

        Vue 的双向数据绑定是其核心特性之一,它可以让视图与数据保持同步,简化了开发者在 DOM 操作上的工作。Vue 的双向数据绑定通过 响应式系统DOM 事件监听 来实现,当数据发生变化时,视图会自动更新;当视图中的元素(如输入框)的值发生变化时,数据也会更新。

        在 Vue 中,双向绑定通常是指通过 v-model 指令在 视图(DOM)模型(数据) 之间建立的双向同步关系。理解 Vue 双向绑定的原理,首先需要了解 Vue 如何实现 数据驱动视图更新视图驱动数据更新,以及它的底层机制是如何工作的。

1. Vue 响应式系统

        Vue 的数据绑定机制基于响应式系统。它通过 数据劫持依赖收集 来保证视图与数据的同步。

        在 Vue 中,响应式系统的核心是 Object.defineProperty(在 Vue 2 中)和 Proxy(在 Vue 3 中),这些技术让 Vue 能够在数据变化时通知视图更新。

1.1 数据劫持(数据监听)

        在 Vue 2 中,当你在 Vue 实例中定义数据时,Vue 会使用 Object.defineProperty() 来将每个数据属性转换为 getter 和 setter,从而拦截对数据的访问和修改。这个过程叫做 数据劫持

  • getter:在访问某个属性时触发,Vue 会记录依赖(即哪些地方用到了这个数据)。
  • setter:在数据发生变化时触发,Vue 会通知相关的依赖(例如视图或计算属性)进行更新。

例如,Vue 对一个对象的 data 属性进行了劫持:

let obj = {message: 'Hello Vue'
};Object.defineProperty(obj, 'message', {get() {console.log('get message');return this._message;},set(newValue) {console.log('set message');this._message = newValue;}
});obj.message = 'Hello World'; // set message
console.log(obj.message); // get message, Hello World

        在 Vue 2 中,当你在模板中使用数据 { { message }},Vue 就会通过 getter 收集依赖(即视图部分),并在数据变化时触发 setter 来更新视图。

1.2 依赖收集

        Vue 会在每个数据属性的 getter 中进行 依赖收集,即当数据属性被读取时,Vue 会记录哪些视图部分(比如 DOM 中的数据绑定)依赖于该数据属性。这些记录下来的部分称为 Watcher,它们是被数据属性监控的观察者。

2. 双向数据绑定的实现

        Vue 的双向数据绑定是通过 指令 v-model 来实现的,v-model 是 Vue 提供的一种语法糖,它允许在视图和数据之间建立双向绑定的关系。v-model 实际上是 v-bindv-on 的组合:v-bind 用于数据的单向绑定,v-on 用于监听 DOM 事件。

2.1 数据到视图的绑定

        Vue 的数据到视图的绑定本质上是通过 响应式系统 来实现的。每当模型(数据)发生变化时,Vue 会通过视图更新来反映数据的最新状态。比如在模板中绑定一个 message 属性:

<div id="app"><p>{{ message }}</p>
</div>

        当 message 的值发生变化时,Vue 会根据响应式系统触发相应的 setter,并通知所有依赖此数据的部分更新视图。Vue 会通过 Watcher 机制,追踪 message 的变化,然后更新视图中的 <p> 标签。

2.2 视图到数据的绑定

        在 v-model 的语法糖中,Vue 会通过监听 DOM 事件来实现视图到数据的绑定。假设我们有一个输入框,并且通过 v-model 将它与 Vue 数据绑定:

<input v-model="message">

        当用户在输入框中输入内容时,输入框会触发 input 事件,Vue 会监听到这个事件并将新的输入值更新到 message 属性中。反之,v-model 也会处理视图到数据的变化(例如,更新 message 后,输入框的值会自动变化)。

Vue 是通过 事件监听器 来捕获输入框的变化,并将其赋值给数据的 message

<input v-bind:value="message" v-on:input="message = $event.target.value">

        这里,v-bind:value="message"message 的值绑定到输入框,v-on:input="message = $event.target.value" 监听输入框的 input 事件并将其值同步回 message

3. Vue 双向绑定的实现原理

    v-model 在 Vue 内部实际上是 数据绑定v-bind)和 事件绑定v-on)的组合。我们可以更详细地分析它是如何实现双向绑定的。

3.1 v-model 的实现过程

在 Vue 中,v-model 是通过以下几个步骤实现双向数据绑定的:

  1. 数据到视图:首先,Vue 会通过 v-bind:valuemessage 的值绑定到 <input> 元素的 value 属性上,确保视图中显示的是 message 的最新值。

  2. 视图到数据:当用户在输入框中输入新的值时,input 事件会被触发,Vue 会监听到该事件并通过 v-on:input 监听输入框的变化,将新的输入值更新到 message 上。

  3. 更新视图:数据 message 变化后,由于 Vue 的响应式系统,相关的视图部分会自动更新,输入框的值会与 message 的新值保持一致。

3.2 双向绑定的核心:v-bindv-on 的结合
  • v-bind: 用来绑定视图中的值到数据(例如,value 属性绑定到 message)。
  • v-on: 用来监听视图的事件,将视图中的输入(input 事件)同步到数据。

        结合起来,v-model 实现了数据和视图之间的双向绑定。当数据变化时,视图更新;当视图变化时,数据更新。

3.3 v-model 的扩展

        在 Vue 3 中,v-model 支持多个修饰符和自定义的事件。例如,你可以使用 v-model 来绑定数组或对象,或者通过修改修饰符(如 .lazy.number 等)来控制数据更新的时机。

<!-- 只有用户输入完成并失去焦点时才更新数据 -->
<input v-model.lazy="message">

4. Vue 2 和 Vue 3 中双向绑定的差异

        在 Vue 2 中,v-model 默认绑定的是 value 属性和 input 事件。Vue 2 在数据和视图之间的双向绑定通过 Object.defineProperty 来劫持数据的 getter 和 setter 实现。

        在 Vue 3 中,v-model 进行了改进。默认情况下,它仍然是绑定 value 属性和 input 事件,但它支持多个 v-model 绑定在同一个组件上,并且可以自定义绑定的属性和事件:

<template><Child v-model:prop="message" />
</template><script>
export default {props: ['prop'],emits: ['update:prop'],methods: {updateMessage(newValue) {this.$emit('update:prop', newValue);}}
};
</script>

总结

        Vue 的双向数据绑定机制基于 响应式系统事件监听。Vue 通过Object.defineProperty(Vue 2)和 Proxy(Vue 3)实现数据的劫持,使得数据变化时能够通知视图更新。通过 v-model,Vue 在数据和视图之间建立了 双向绑定,在数据变化时更新视图,在视图变化时更新数据。这种机制极大地提高了开发效率,简化了数据和界面同步的复杂度。

相关文章:

Vue 双向数据绑定的原理

Vue 的双向数据绑定是其核心特性之一&#xff0c;它可以让视图与数据保持同步&#xff0c;简化了开发者在 DOM 操作上的工作。Vue 的双向数据绑定通过 响应式系统 和 DOM 事件监听 来实现&#xff0c;当数据发生变化时&#xff0c;视图会自动更新&#xff1b;当视图中的元素&am…...

Spring Web MVC项目的创建及使用

一、什么是Spring Web MVC&#xff1f; Spring Web MVC 是基于 Servlet API 构建的原始 Web 框架&#xff0c;从⼀开始就包含在 Spring 框架中&#xff0c;通常被称为Spring MVC。 1.1 MVC的定义 MVC 是 Model View Controller 的缩写&#xff0c;它是软件工程中的一种软件架构…...

32.日常算法

1.最大子数组和 题目来源 给你一个整数数组 nums &#xff0c;请你找出一个具有最大和的连续子数组&#xff08;子数组最少包含一个元素&#xff09;&#xff0c;返回其最大和。子数组是数组中的一个连续部分。 示例 1&#xff1a; 输入&#xff1a;nums [-2,1,-3,4,-1,2,1,…...

MySQL的底层原理与架构

前言 了解MySQL的架构和原理对于很多的后续很多的操作会有很大的帮助与理解。并且很多知识都与底层架构相关联。 了解MySQL架构 通过上面的架构图可以得知&#xff0c;Server层中主要由 连接器、查询缓存、解析器/分析器、优化器、执行器 几部分组成的&#xff0c;下面将主要…...

python Excel 表读取合并单元格以及清除空格符

读取合并单元格并保留合并信息 读取合并单元格并保留合并信息清除各单元格的空格和换行符&#xff0c;并去除列名中的空格和换行符 读取合并单元格并保留合并信息 当我们只是使用 pandas 的 read_excel 方法读取 Excel 文件时&#xff0c;我们可能会遇到一个很棘手的问题&…...

Node.js 实现简单爬虫

介绍 爬虫是一种按照一定的规则&#xff0c;自动地抓取万维网信息的程序或者脚本。 本文将使用 Nodejs 编写一个简单的爬虫脚本&#xff0c;爬取一个美食网站&#xff0c;获取菜品的标题和图片链接&#xff0c;并以表格的形式输出。 准备工作 1、初始化项目 首先&#xff0…...

【Pytorch】nn.RNN、nn.LSTM 和 nn.GRU的输入和输出形状

nn.RNN、nn.LSTM 和 nn.GRU的输入和输出形状 输入形状通用输入参数特殊情况&#xff08;LSTM&#xff09; 输出形状nn.RNN 和 nn.GRUnn.LSTM 代码示例 输入形状 通用输入参数 这三个模块通常接收以下两种形式的输入&#xff1a; 输入序列&#xff1a;形状为 (seq_len, batch…...

代码随想录算法训练营第三十一天| 回溯算法04

491. 递增子序列 题目&#xff1a; 代码随想录 视频讲解&#xff1a;回溯算法精讲&#xff0c;树层去重与树枝去重 | LeetCode&#xff1a;491.递增子序列_哔哩哔哩_bilibili 这题需要注意的点&#xff1a; 1. path长度在2以上才放入最终结果 2. 需要记录已经使用过的数字&am…...

2024.1版android studio创建Java语言项目+上传gitee

1.在gitee上创建仓库 Gitee 创建仓库并邀请成员指南_gitee创建仓库邀请成员-CSDN博客 见1 2.新建android studio项目 3.在Android studio配置gitee Android Studio提交代码到gitee仓库_android log in to gitee-CSDN博客 其中的一二步 p.s.添加gitee账户选择password时&a…...

React 打印插件 -- react-to-print

一、安装依赖 npm install react-to-print 二、使用 import { useReactToPrint } from "react-to-print"; import React, { useRef, forwardRef } from react;const Content () > {const contentRef useRef(null);const reactToPrintFn useReactToPrint({ c…...

opentelemetry-collector 配置elasticsearch

一、修改otelcol-config.yaml receivers:otlp:protocols:grpc:endpoint: 0.0.0.0:4317http:endpoint: 0.0.0.0:4318 exporters:debug:verbosity: detailedotlp/jaeger: # Jaeger supports OTLP directlyendpoint: 192.168.31.161:4317tls:insecure: trueotlphttp/prometheus: …...

SQL Server 数据库迁移到 MySQL 的完整指南

文章目录 引言一、迁移前的准备工作1.1 确定迁移范围1.2 评估兼容性1.3 备份数据 二、迁移工具的选择2.1 使用 MySQL Workbench2.2 使用第三方工具2.3 手动迁移 三、迁移步骤3.1 导出 SQL Server 数据库结构3.2 转换数据类型和语法3.3 导入 MySQL 数据库3.4 迁移数据3.5 迁移存…...

C# SQlite使用流程

前言 不是 MySQL 用不起&#xff0c;而是 SQLite 更有性价比&#xff0c;绝大多数的应用 SQLite 都可以满足。 SQLite 是一个用 C 语言编写的开源、轻量级、快速、独立且高可靠性的 SQL 数据库引擎&#xff0c;它提供了功能齐全的数据库解决方案。SQLite 几乎可以在所有的手机…...

MySQL数据库 (三)- 函数/约束/多表查询/事务

目录 一 函数 (一 字符串函数 (二 数值函数 (三 日期函数 (四 流程函数 二 约束 (一 概述 (二 约束演示 (三 外键约束 三 多表查询 (一 多表关系 1 一对多&#xff08;多对一&#xff09; 2 多对多 3 一对一 (二 多表查询概述 (三 内连接 1 查询语法 2 代码实…...

【玩转 Postman 接口测试与开发2_018】第14章:利用 Postman 初探 API 安全测试

《API Testing and Development with Postman》最新第二版封面 文章目录 第十四章 API 安全测试1 OWASP API 安全清单1.1 相关背景1.2 OWASP API 安全清单1.3 认证与授权1.4 破防的对象级授权&#xff08;Broken object-level authorization&#xff09;1.5 破防的属性级授权&a…...

攻防世界baigeiRSA

打开题目附件 import libnum from Crypto.Util import number from secret import flagsize 128 e 65537 p number.getPrime(size) q number.getPrime(size) n p*qm libnum.s2n(flag) c pow(m, e, n)print(n %d % n) print(c %d % c)n 8850300144784503160345704866…...

12.7 LangChain代理系统Agents深度解析:构建自主决策的智能体应用

LangChain代理系统Agents深度解析:构建自主决策的智能体应用 一、代理系统的核心价值 代理系统是大模型应用的决策中枢,通过动态工具调度和任务分解,突破传统链式流程的三大局限: 动态规划:根据实时反馈调整执行路径工具集成:无缝对接500+外部系统API认知迭代:通过记忆…...

解释一下数据库中的事务隔离级别,在 Java 中如何通过 JDBC设置事务隔离级别?

数据库中的事务隔离级别是用于控制并发事务之间相互影响的一种机制。 它定义了事务之间的可见性和影响范围&#xff0c;常见的隔离级别包括&#xff1a; 读未提交&#xff08;Read Uncommitted&#xff09;&#xff1a;最低的隔离级别&#xff0c;事务中的修改即使没有提交也…...

[NKU]C++安装环境 VScode

bilibili安装教程 vscode 关于C/C的环境配置全站最简单易懂&#xff01;&#xff01;大学生及初学初学C/C进&#xff01;&#xff01;&#xff01;_哔哩哔哩_bilibili 1安装vscode和插件 汉化插件 ​ 2安装插件 2.1 C/C 2.2 C/C Compile run ​ 2.3 better C Syntax ​ 查看已…...

Node.js 环境配置

什么是 Node.js Node.js 是一个基于 Chrome V8 JavaScript 引擎的 JavaScript 运行时环境&#xff0c;它允许你在服务器端运行 JavaScript。传统上&#xff0c;JavaScript 主要用于浏览器中的前端开发&#xff0c;而 Node.js 使得 JavaScript 也能够在服务器上执行&#xff0c;…...

1Panel应用推荐:WordPress开源博客软件和内容管理系统

1Panel&#xff08;github.com/1Panel-dev/1Panel&#xff09;是一款现代化、开源的Linux服务器运维管理面板&#xff0c;它致力于通过开源的方式&#xff0c;帮助用户简化建站与运维管理流程。为了方便广大用户快捷安装部署相关软件应用&#xff0c;1Panel特别开通应用商店&am…...

C++:string类的模拟实现

目录 1.引言 2.C模拟实现 2.1模拟实现构造函数 1&#xff09;直接构造 2&#xff09;拷贝构造 2.2模拟实现析构函数 2.3模拟实现其他常规函数 1&#xff09;c_str函数 2&#xff09;size函数 3&#xff09;begin/end函数 4&#xff09;reserve函数 5&#xff09;re…...

DMZ区的作用和原则

DMZ&#xff08;Demilitarized Zone&#xff0c;非军事化区&#xff09;是网络安全架构中一个重要的概念&#xff0c;其主要作用和原则如下&#xff1a; DMZ的作用 隔离风险 DMZ作为内外网络之间的缓冲区&#xff0c;能够有效隔离外部网络的攻击风险。将对外提供服务的服务器&…...

21.命令模式(Command Pattern)

定义 命令模式&#xff08;Command Pattern&#xff09; 是一种行为型设计模式&#xff0c;它将请求封装成一个对象&#xff0c;从而使您可以使用不同的请求、队列、日志请求以及支持撤销操作等功能。命令模式通过将请求&#xff08;命令&#xff09;封装成对象&#xff0c;使…...

如何将本地 Node.js 服务部署到宝塔面板:完整的部署指南

文章简介&#xff1a; 将本地开发的 Node.js 项目部署到线上服务器是开发者常见的工作流程之一。在这篇文章中&#xff0c;我将详细介绍如何将本地的 Node.js 服务通过宝塔面板&#xff08;BT 面板&#xff09;上线。宝塔面板是一个强大的服务器管理工具&#xff0c;具有简洁的…...

4.3 线性回归的改进-岭回归/4.4分类算法-逻辑回归与二分类/ 4.5 模型保存和加载

4.3.1 带有L2正则化的线性回归-岭回归 岭回归&#xff0c;其实也是一种线性回归&#xff0c;只不过在算法建立回归方程的时候1&#xff0c;加上正则化的限制&#xff0c;从而达到解决过拟合的效果 4.3.1.1 API 4.3.1.2 观察正则化程度的变化&#xff0c;对结果的影响 正则化力…...

Mac 部署Ollama + OpenWebUI完全指南

文章目录 &#x1f4bb; 环境说明&#x1f6e0;️ Ollama安装配置1. 安装[Ollama](https://github.com/ollama/ollama)2. 启动Ollama3. 模型存储位置4. 配置 Ollama &#x1f310; OpenWebUI部署1. 安装Docker2. 部署[OpenWebUI](https://www.openwebui.com/)&#xff08;可视化…...

工业物联网平台-视频识别视频报警新功能正式上线

前言 视频监控作为中服云工业物联网平台4.0的功能已经上线运行。已为客户服务2年有余&#xff0c;为客户提供多路视频、实时在线监视和控制能力。服务客户实时发现现场、产线、设备出现随机故障、事故等&#xff0c;及时到场处理维修。 视频识别&视频报警新功能当前正式上…...

面试题 17.19. 消失的两个数字

文章目录 1.题目2.思路3.代码 1.题目 面试题 17.19. 消失的两个数字 给定一个数组&#xff0c;包含从 1 到 N 所有的整数&#xff0c;但其中缺了两个数字。你能在 O(N) 时间内只用 O(1) 的空间找到它们吗&#xff1f; 以任意顺序返回这两个数字均可。 示例 1: **输入:** […...

Licode简介及与SRS对比

Licode 是一个开源的 WebRTC 通信框架,专注于多人实时音视频互动(如视频会议),而 SRS 是一个通用的 流媒体服务器,支持直播、低延迟流分发等场景。以下是两者的详细对比和 Licode 的核心解析: 一、Licode 核心解析 1. 定位与设计目标 核心功能:基于 WebRTC 的多人实时音…...