vue的双向绑定是怎么实现的
Vue.js 的双向绑定是通过 数据劫持(Data Observation) 和 发布-订阅模式(Publish-Subscribe Pattern) 实现的。具体来说,Vue 使用了以下核心技术:
-
数据劫持:通过
Object.defineProperty或Proxy监听数据的变化。 -
依赖收集:在数据读取时收集依赖(Watcher)。
-
派发更新:在数据变化时通知依赖更新。
以下是 Vue 双向绑定的实现原理和详细步骤:
1. 数据劫持
Vue 通过数据劫持监听数据的变化。在 Vue 2.x 中,使用 Object.defineProperty;在 Vue 3.x 中,使用 Proxy。
(1)Vue 2.x:Object.defineProperty
-
原理:通过
Object.defineProperty将对象的属性转换为getter和setter。 -
示例:
function defineReactive(obj, key, val) {Object.defineProperty(obj, key, {get() {console.log(`读取 ${key}: ${val}`);return val;},set(newVal) {if (newVal !== val) {console.log(`设置 ${key}: ${newVal}`);val = newVal;}},});
}const data = {};
defineReactive(data, 'message', 'Hello');
console.log(data.message); // 读取 message: Hello
data.message = 'World'; // 设置 message: World
(2)Vue 3.x:Proxy
-
原理:通过
Proxy监听整个对象的变化,支持动态添加属性。 -
示例:
function reactive(obj) {return new Proxy(obj, {get(target, key) {console.log(`读取 ${key}: ${target[key]}`);return target[key];},set(target, key, newVal) {if (target[key] !== newVal) {console.log(`设置 ${key}: ${newVal}`);target[key] = newVal;}return true;},});
}const data = reactive({ message: 'Hello' });
console.log(data.message); // 读取 message: Hello
data.message = 'World'; // 设置 message: World
2. 依赖收集
Vue 在数据读取时收集依赖(Watcher),在数据变化时通知依赖更新。
(1)Watcher
-
作用:Watcher 是 Vue 中的观察者,负责监听数据的变化并执行回调。
-
示例:
class Watcher {constructor(vm, key, updateFn) {this.vm = vm;this.key = key;this.updateFn = updateFn;// 触发 getter,收集依赖Dep.target = this;this.vm[this.key];Dep.target = null;}update() {this.updateFn.call(this.vm, this.vm[this.key]);}
}
(2)Dep
-
作用:Dep 是依赖管理器,负责存储 Watcher 并通知更新。
-
示例:
class Dep {constructor() {this.subscribers = [];}depend() {if (Dep.target) {this.subscribers.push(Dep.target);}}notify() {this.subscribers.forEach(sub => sub.update());}
}
(3)结合数据劫持和依赖收集
-
在
getter中收集依赖,在setter中派发更新。 -
示例:
function defineReactive(obj, key, val) {const dep = new Dep();Object.defineProperty(obj, key, {get() {if (Dep.target) {dep.depend(); // 收集依赖}return val;},set(newVal) {if (newVal !== val) {val = newVal;dep.notify(); // 派发更新}},});
}
3. 派发更新
当数据变化时,Vue 会通知所有依赖(Watcher)更新视图。
示例:
const data = {};
defineReactive(data, 'message', 'Hello');new Watcher(data, 'message', (value) => {console.log(`视图更新: ${value}`);
});data.message = 'World'; // 设置 message: World -> 视图更新: World
4. 双向绑定的实现
Vue 的双向绑定是通过 v-model 指令实现的。v-model 是 v-bind 和 v-on 的语法糖。
(1)v-model 的原理
-
v-bind:将数据绑定到视图。 -
v-on:监听视图的变化并更新数据。
(2)示例
<input v-model="message" />
等价于:
<input :value="message" @input="message = $event.target.value" />
5. Vue 3.x 的改进
在 Vue 3.x 中,使用 Proxy 替代 Object.defineProperty,解决了以下问题:
-
动态添加属性:
Proxy可以监听动态添加的属性。 -
性能优化:
Proxy的性能优于Object.defineProperty。
6. 总结
Vue 的双向绑定是通过以下步骤实现的:
-
数据劫持:使用
Object.defineProperty或Proxy监听数据的变化。 -
依赖收集:在数据读取时收集依赖(Watcher)。
-
派发更新:在数据变化时通知依赖更新。
-
双向绑定:通过
v-model实现视图和数据的双向同步。
通过这种机制,Vue 实现了高效的双向绑定,使得开发者可以专注于业务逻辑,而无需手动操作 DOM。
相关文章:
vue的双向绑定是怎么实现的
Vue.js 的双向绑定是通过 数据劫持(Data Observation) 和 发布-订阅模式(Publish-Subscribe Pattern) 实现的。具体来说,Vue 使用了以下核心技术: 数据劫持:通过 Object.defineProperty 或 Prox…...
在 Mac mini M2 上本地部署 DeepSeek-R1:14B:使用 Ollama 和 Chatbox 的完整指南
随着人工智能技术的飞速发展,本地部署大型语言模型(LLM)已成为许多技术爱好者的热门选择。本地部署不仅能够保护隐私,还能提供更灵活的使用体验。本文将详细介绍如何在 Mac mini M2(24GB 内存)上部署 DeepS…...
docker-compose部署onlyoffice8.3.0并支持ssl,且支持通过nginx代理,关闭JWT配置
编写docker-compose文件 mkdir -p /data/onlyoffice && echo "version: 3services:onlyoffice:container_name: OnlyOfficeimage: onlyoffice/documentserver:8.3.0restart: alwaysports:- 8088:80- 64431:443environment:TZ: Asia/ShanghaiJWT_ENABLED: falsevol…...
如何配置虚拟机的IP上网
要配置虚拟机的IP地址以便上网,你可以按照以下步骤操作: 打开虚拟机软件,确保虚拟机的网络设置为“桥接模式”或“NAT模式”,这样虚拟机可以与物理网络连接。 在虚拟机操作系统中,打开网络设置界面,一般在…...
【tplink】校园网接路由器如何单独登录自己的账号,wan-lan和lan-lan区别
老式路由器TPLINK,接入校园网后一人登录,所有人都能通过连接此路由器上网,无法解决遂上网搜索,无果,幸而偶然看到一个帖子说要把信号源网线接入路由器lan口,开启新世界。 一、wan-lan,lan-lan区…...
Python--内置模块和开发规范(下)
2. 开发规范 2.1 单文件应用 文件结构示例 # 文件注释 import os import jsonDB_PATH "data.json" # 常量放顶部def load_data():"""函数注释:加载数据"""if os.path.exists(DB_PATH):with open(DB_PATH, "r"…...
DeepSeek开源周Day5压轴登场:3FS与Smallpond,能否终结AI数据瓶颈之争?
2025年2月28日,DeepSeek开源周迎来了第五天,也是本次活动的收官之日。自2月24日启动以来,DeepSeek团队以每天一个开源项目的节奏,陆续向全球开发者展示了他们在人工智能基础设施领域的最新成果。今天,他们发布了Fire-F…...
[密码学实战]Java实现SM2数字信封(结合SM4对称加密)生成与解析
一、代码运行结果 二、什么是数字信封 2.1 基本概念 数字信封(Digital Envelope) 是一种结合对称加密与非对称加密的混合加密技术,通过以下步骤实现高效安全的数据传输: 对称加密:使用SM4算法加密原始数据,处理速度快,适合大数据量。非对称加密:使用SM2公钥加密SM4密…...
redis序列化设置
redis序列化设置 redis序列化设置序列化对象里有org.joda.time.DateTime1)、报错内容如下2)、解决方案:分别自定义时间的序列化和反序列化,以对象形式关联到redisTemplate redis序列化设置 redis序列化设置,通过自定义…...
Sqlserver安全篇之_TLS的证书概念
证书的理解 参考Sqlserver的官方文档https://learn.microsoft.com/zh-cn/sql/database-engine/configure-windows/certificate-overview?viewsql-server-ver16 TLS(Transport Layer Security)传输层安全和SSL(Secure Sockets Layer)安全套接字层协议位于应用程序协议层和TCP/…...
【HarmonyOS Next】 鸿蒙应用useNormalizedOHMUrl详解
【HarmonyOS Next】 鸿蒙应用useNormalizedOHMUrl详解 一、useNormalizedOHMUrl是什么? useNormalizedOHMUrl指的是是否使用标准化OHMUrl拼接。 在开发过程中,需要根据不同的环境或配置动态生成 URL。例如,在加载一些远程模块或者资源时,…...
Oracle 查询表空间使用情况及收缩数据文件
本文介绍Oracle收缩数据文件的相关操作,运维工作中有时会需要通过收缩数据文件来释放磁盘空间。 数据文件初始化方式: 1.我们创建表空间一般有两种方式初始化其数据文件,即指定初始大小为32G(很大的值)或指定初始大小为…...
怎么进行mysql的优化?
MySQL 的优化是一个系统性的工作,涉及多个层面,包括查询优化、索引优化、配置优化、架构优化等。以下是一些常见的 MySQL 优化方法: 查询优化 避免全表扫描:确保查询能够使用索引,避免 SELECT *,只选择需要…...
docker-compose方式启动Kafka Sasl加密认证(无zk)
首先参考文档,思考过程可以进行参考https://juejin.cn/post/7294556533932884020#heading-3 用的镜像是Bitnami,对SASL配置进行了简化,需要按照特定格式去配置jass验证 完整配置如下 镜像版本参考:https://hub.docker.com/r/bitn…...
Grafana接入Zabbix数据源
1. 对接 Zabbix 1.1 安装 Zabbix 插件 在线安装: 1.2 配置 Zabbix 数据源 点击 Configuration > Data Sources > Add data source。选择 Zabbix,填写: URL:http://<zabbix-server>/api_jsonrpc.phpUsername&#x…...
华为在不同发展时期的战略选择(节选)
华为在不同发展时期的战略选择(节选) 添加图片注释,不超过 140 字(可选) 来源:谢宁专著《华为战略管理法:DSTE实战体系》。本文有节选修改。 导言 从目前所取得的成就往回看,华为…...
【计算机网络】TCP协议相关总结,TCP可靠性的生动讲解
TCP 可靠性 确保快递不丢、不乱、不过载 机制作用(快递类比)防止的问题检验和检查包裹是否损坏,损坏就重新发数据出错序列号给每个包裹编号,按顺序整理乱序、重复确认应答每送到一件,就让收件人签收丢失滑动窗口控制…...
lua基础语法学习
lua基础语法学习 文章目录 lua基础语法学习1. 基础2. 输入输出3. 分支结构与循环结构4. 函数5. 元表与元方法6. 面向对象 1. 基础 注释 --单行注释--[[ 多行注释 --]]标识符 标识符以一个字母 A 到 Z 或 a 到 z 或下划线 _ 开头后加上 0 个或多个字母,下划线&…...
【个人开发】deepspeed+Llama-factory 本地数据多卡Lora微调【完整教程】
文章目录 1.背景2.微调方式2.1 关键环境版本信息2.2 步骤2.2.1 下载llama-factory2.2.2 准备数据集2.2.3 微调模式2.2.3.1 zero-1微调2.2.3.2 zero-2微调2.2.3.3 zero-3微调2.2.3.4 单卡Lora微调 2.2.4 实验2.2.4.1 实验1:多GPU微调-zero12.2.4.2 实验2:…...
【SpringBoot】数据访问技术spring Data、 JDBC、MyBatis、JSR-303校验
Spring Boot 数据访问技术及特性 目录标题 Spring Boot 数据访问技术及特性摘要1. 引言2. Spring Data架构与原理2.1 Spring Data概述2.2 Spring Data核心组件2.3 Spring Boot与Spring Data的集成机制 3. Spring Boot与JDBC的整合3.1 JDBC整合流程3.2 数据源自动配置3.3 JdbcTe…...
手机放兜里,支付宝“碰一下”被盗刷?
大家好,我是小悟。 近期,网络上关于“支付宝‘碰一下’支付易被盗刷”的传言甚嚣尘上,不少用户对此心生疑虑。 首先,要明确一点:“碰一下”支付并不会像某些传言中所描述的那样容易被隔空盗刷。这一观点已经得到了支付…...
Java Web应用中获取客户端的真实IP地址
Java Web应用中获取客户端的真实IP地址,尤其在存在代理服务器的情况下。 代码示例: public static String getClientIP(HttpServletRequest request) {String ip = parseCommaSeparatedIPs(request.getHeader("X-Forwarded-For"));if (isInvalid(ip)) {ip = pars…...
vue框架后遗症∶被遗忘的dom操作
用多了vue、react等前端框架,不得不说用数据驱动视图来开发真的很香,但是也免不了会有不用这些框架的项目,dom操作还是很有必要的,一开始学习网页设计的时候就教过,后面一直开发项目基本上用框架。虽然有些想不起来了&…...
基于深度学习+NLP豆瓣电影数据爬虫可视化推荐系统
博主介绍:资深开发工程师,从事互联网行业多年,熟悉各种主流语言,精通java、python、php、爬虫、web开发,已经做了多年的设计程序开发,开发过上千套设计程序,没有什么华丽的语言,只有…...
8. 示例:对32位数据总线实现位宽和值域覆盖
文章目录 前言示例一:示例二:示例三:仿真与覆盖率分析覆盖点详细说明覆盖率提升技巧常见错误排查 示例四:仿真步骤 前言 针对32位数据总线实现位宽和值域的覆盖,并且能够用xrun运行,查看日志和波形。cover…...
深度剖析Seata源码:解锁分布式事务处理的核心逻辑
文章目录 写在文章开头如何使用源码(配置转掉)基于AT模式详解Seata全链路流程Seata服务端启动本地服务如何基于GlobalTransaction注解开启事务客户端如何开启分布式事务RM和TC如何协调处理分支事务RM生成回滚日志事务全局提交与回滚小结参考写在文章开头 在当今分布式系统日益…...
快速列出MS Word中所有可用字体
Word中有很多字体,虽然在字体下拉列表中提供了字体的样例,但是并不全面,例如使用Batang字体的话,数字会显示成什么效果,就无法直观的看到。 打开Word应用程序,新建一个空白文档,按AltF11打开VBE…...
SpringDataJPA使用deleteAllInBatch方法逻辑删除失效
概述 在使用Spring Boot JPA时,执行批量删除操作时,遇到逻辑删除失效的问题。具体而言,当使用deleteAllInBatch方法时,数据会被物理删除,而不是进行逻辑删除;但是当使用deleteAll时,逻辑删除操…...
【密码学实战】Java 实现 SM2 国密算法(签名带id、验签及 C1C3C2 加密解密)
前言 SM2是中国国家密码管理局发布的椭圆曲线公钥密码算法标准(GB/T 32918),属于国密算法体系。与RSA和ECDSA相比,SM2在相同安全强度下密钥更短、计算效率更高。本文将介绍如何在Java中实现SM2的密钥生成、数字签名、验签、加密及…...
flex布局自定义一行几栏,靠左对齐===grid布局
模板 <div class"content"><div class"item">1222</div><div class"item">1222</div><div class"item">1222</div><div class"item">1222</div><div class"…...
