【Vue】响应式与数据劫持
Vue.js 是一个渐进式的 JavaScript 框架,其中最重要的一个特性就是响应式(Reactivity)。Vue 借助数据劫持(Data Observation)技术实现了对数据的响应式更新,当数据发生变化时,它会自动重新渲染视图,这使得构建复杂的用户界面变得更加容易。
在本文中,我们将介绍 Vue.js 中的响应式原理和数据劫持机制,让你了解 Vue.js 是如何通过监听数据变化来实现视图更新。
响应式原理
Vue.js 的响应式原理是基于数据驱动的,它的核心是将数据和视图进行关联,并且在数据发生变化时更新视图。Vue.js 通过数据劫持技术实现了响应式原理。
所谓数据劫持,就是通过一些手段来劫持 JavaScript 对象的访问和修改,以便在数据发生变化时能够自动更新视图。
Vue.js 中的响应式原理流程如下:
1. Vue 组件中有一个 data 属性,它是一个对象。
2. Vue 在初始化组件时,会通过 Object.defineProperty() 方法将 data 中的所有属性都转化成 getter 和 setter。
3. 当访问或者修改这些属性时,会触发对应的 getter 和 setter 方法。
4. 在 setter 方法中,Vue 会通知相关的 Watcher(一个观察者对象)去更新视图。
5. 当组件中的 data 发生变化时,会触发对应属性的 setter 方法,然后通知相关的 Watcher 更新视图。
下面我们将详细介绍 Vue.js 中的数据劫持技术。
数据劫持
数据劫持是 Vue.js 实现响应式的核心技术之一,它主要通过 Object.defineProperty() 方法来实现。Object.defineProperty() 方法是 JavaScript 原生提供的 API,它可以用来定义对象上的属性。这个方法有三个参数:
Object.defineProperty(obj, prop, descriptor)
* obj:要定义属性的对象。
* prop:要定义或修改的属性的名称。
* descriptor:要定义或修改的属性的描述符。descriptor 是一个包含属性的特性的对象,它具有以下几个属性:
* configurable:当且仅当该属性的 configurable 为 true 时,该属性描述符才能够被改变,同时该属性也能够被删除,默认为 false。
* enumerable:当且仅当该属性的 enumerable 为 true 时,该属性才会出现在对象的枚举属性中,默认为 false。
* value:该属性对应的值,默认为 undefined。
* writable:当且仅当该属性的 writable 为 true 时,该属性才能被赋值运算符改变,默认为 false。
* get:表示该属性的 getter 函数,默认为 undefined。
* set:表示该属性的 setter 函数,默认为 undefined。
通过 Object.defineProperty() 方法,可以给对象的属性设置 getter 和 setter。这样一来,我们就可以在属性被访问或者修改时,触发对应的 getter 和 setter 方法,达到数据劫持的目的。
在 Vue.js 中,当初始化组件时,Vue.js 会对组件中所有的 data 属性使用 Object.defineProperty() 方法将其转化为 getter 和 setter。这样一来,当组件中的 data 属性被访问或者修改时,Vue.js 就能够捕获到这些操作,并在内部执行相应的逻辑。这就实现了 Vue.js 中的响应式机制。
下面是一个简单的示例,我们将使用 Object.defineProperty() 方法来实现一个响应式对象:
var obj = {};Object.defineProperty(obj, "name", {get: function() {console.log("访问了属性 name");return this._name;},set: function(value) {console.log("修改了属性 name,新值为:" + value);this._name = value;}
});obj.name = "Vue.js";
console.log(obj.name);
在这个示例中,我们使用 Object.defineProperty() 方法定义了一个对象 obj 的属性 name。在 getter 和 setter 中,我们分别输出了访问和修改属性的操作,并打印出了属性的值。当我们执行 obj.name = "Vue.js" 时,会触发 setter 方法,并输出修改操作的信息。当我们访问 obj.name 时,会触发 getter 方法,并输出访问操作的信息。
响应式实现
在了解了数据劫持的原理之后,我们来看看 Vue.js 是如何实现响应式的。
我们先来看一个简单的示例,下面是一个 Vue 组件的代码:
<div id="app"><p>{{ message }}</p>
</div>
<script>
new Vue({el: "#app",data: {message: "Hello, Vue.js!"}
});
</script>
在这个组件中,我们使用了 Vue.js 的数据绑定语法 {{ message }} 来显示 data 中的 message 属性。在初始化时,Vue.js 会将组件中的 data 属性转化为 getter 和 setter,代码如下:
function defineReactive(obj, key, val) {Object.defineProperty(obj, key, {get: function() {console.log("访问了属性 " + key);return val;},set: function(newVal) {console.log("修改了属性 " + key + ",新值为:" + newVal);val = newVal;}});
}function observe(obj) {if (!obj || typeof obj !== "object") {return;}Object.keys(obj).forEach(function(key) {defineReactive(obj, key, obj[key]);});
}function Vue(options) {this._data = options.data;observe(this._data);
}
在这个代码中,我们定义了三个函数:defineReactive()、observe() 和 Vue()。
* defineReactive():这个函数用来给对象添加 getter 和 setter,实现数据劫持。
* observe():这个函数会递归遍历对象中的所有属性,将其转化为 getter 和 setter。
* Vue():这个函数用来初始化 Vue 组件,其中 options.data 属性就是我们要响应式的数据。
我们在 Vue() 函数中调用了 observe(),将 data 属性转化为 getter 和 setter。在 defineReactive() 函数中,我们调用了 Object.defineProperty() 方法,将 data 中的每个属性都转化为 getter 和 setter。这样一来,当我们访问或者修改组件中的 data 属性时,就会触发相应的 getter 和 setter 方法,打印出访问或者修改属性的信息。
我们来运行一下这个示例,在控制台中可以查看到输出的信息:
访问了属性 message
Hello, Vue.js!
修改了属性 message,新值为:Hello, Vue.js!
访问了属性 message
Hello, Vue.js!
在这个示例中,我们成功地将组件中的 data 属性转化为了响应式的数据。当我们访问或者修改属性时,都会触发对应的 getter 和 setter 方法,并输出相应的信息。
数据更新
数据劫持的目的是为了在数据发生变化时,能够自动更新视图。在 Vue.js 中,当数据发生变化时,会触发相应的 getter 和 setter 方法,然后通知相关的 Watcher 更新视图。
Watcher 是 Vue.js 中核心的观察者对象,它可以监听数据的变化,当数据发生变化时,会触发更新视图的操作。
当一个 Vue 组件被创建时,会创建一个渲染 Watcher,它会监听组件中的模板(template)和 data 数据。当组件中的 data 数据发生变化时,渲染 Watcher 就会重新渲染组件。
当我们在组件中访问 data 数据时,就会触发一次 getter 方法,并将当前的 Watcher 添加到一个全局的栈中。这个栈叫做 Dep(依赖),它会保存当前的 Watcher 实例。
当 data 数据发生变化时,会触发对应的 setter 方法,并通知 Dep 中保存的所有 Watcher 实例进行更新操作。
在更新时,渲染 Watcher 会先将组件的 VNode(虚拟 DOM)重新渲染,然后再将新的 VNode 与旧的 VNode 进行比对,找出需要更新的部分,最后将差异更新到真实的 DOM 上。
总结
Vue.js 的响应式原理是基于数据驱动的,它通过数据劫持技术实现了对数据的响应式更新。当数据发生变化时,会自动重新渲染视图。
Vue.js 的数据劫持技术是通过 Object.defineProperty() 方法来实现的,这个方法可以定义对象上的属性,并给属性设置 getter 和 setter,达到数据劫持的目的。
在 Vue.js 中,当组件中的 data 数据发生变化时,会触发对应的 setter 方法,并通知相关的 Watcher 更新视图。
在更新视图时,Vue.js 会先重新渲染 VNode,然后进行差异比对,更新差异部分到真实的 DOM 上。
相关文章:
【Vue】响应式与数据劫持
Vue.js 是一个渐进式的 JavaScript 框架,其中最重要的一个特性就是响应式(Reactivity)。Vue 借助数据劫持(Data Observation)技术实现了对数据的响应式更新,当数据发生变化时,它会自动重新渲染视…...
Modbus RTU转Profinet网关连接PLC与变频器通讯在机床上应用案例
背景:以前在机床加工车间里,工人们忙碌地操作着各种机床设备。为了使整个生产过程更加高效、流畅,进行智能化改造。 方案:在机床上,PLC通过Modbus RTU转Profinet网关连接变频器进行通讯:PLC作为整个生产线…...
Autoware 整体架构
Autoware 整体架构 测试...
【maven】手动指定jar推送
说明 为了推送第三方的jar,有时需要指定对应的jar推送到私有仓库。 示例 mvn deploy:deploy-file --settings /home/xxx/.m2/settings.xml -DgroupIdgroupId的值 -DartifactIdartifactId的值 -Dversionjar包的版本号 -Dpackagingjar -Dfilejar的路径 -Durlhttp:/…...
算法---定长子串中元音的最大数目
题目 给你字符串 s 和整数 k 。 请返回字符串 s 中长度为 k 的单个子字符串中可能包含的最大元音字母数。 英文中的 元音字母 为(a, e, i, o, u)。 示例 1: 输入:s “abciiidef”, k 3 输出:3 解释:…...
美国汽车零部件巨头 AutoZone 遭遇网络攻击
Security Affairs 网站披露,美国汽车配件零售商巨头 AutoZone 称其成为了 Clop MOVEit 文件传输网络攻击的受害者,导致大量数据泄露。 AutoZone 是美国最大的汽车零配件售后市场经销商之一,在美国、墨西哥、波多黎各、巴西和美属维尔京群岛经…...
WPF面试题入门篇
入门篇[2] 1. 谈谈什么是WPF? WPF(Windows Presentation Foundation)是微软公司开发的一种用于创建Windows应用程序的用户界面框架。它是.NET Framework的一部分,提供了一种基于XAML(可扩展应用程序标记语言…...
opencv-ORB检测
ORB(Oriented FAST and Rotated BRIEF)是一种图像特征检测和描述算法,结合了 FAST 关键点检测器和 BRIEF 描述子的优点。ORB 算法具有良好的性能,特别适用于实时应用,如目标追踪、相机定位等。 以下是 ORB 算法的一般…...
please upgrade numpy version to >=1.20
升级 upgrade numpy_升级numpy-CSDN博客 pip install numpy --upgrade 没有pip conda install numpy --upgrade 会报错 conda list numpy来查看numpy版本 似乎这个numpy要看numpy-base这个 似乎没有pip...
关于进制的转化
二进制转十进制: 🔰 方法一:二进制转十进制,用各数的码位与位权的乘积之和,说白了就是用从右到左的每个数去乘以2的幂次方(最右边是0),然后就所有的数相加。 补充:位权是…...
JVM 之 字节码指令
目录 一. 前言 二. 指令集 2.1. 支持的数据类型 2.2. 指令分类 三. 指令手册 3.1. 操作数栈 3.2. 运算与转换 3.3. 条件转移 3.4. 类与数组 3.5. 调度与返回加 finally 3.6. 指令手册汇总 3.7. 示例 一. 前言 字节码指令集的特点是数据量短小精干,便于传…...
阿里云跨账号建立局域网
最近有活动,和好友一并薅了下阿里云的羊毛。琢磨着两台机器组一个局域网,于是有了这个需求,把步骤记录一下: 假设两台机器叫A和B,我们开始进行建立和组网 1. 建立ECS 把A机器公共环境装好,然后使用《实例与…...
【OpenSTL】方便好用的时空预测开源库
OpenSTL:方便好用的时空预测开源库 时空预测学习是一种学习范式,它使得模型能够通过在无监督的情况下从给定的过去帧预测未来帧,从而学习空间和时间的模式。尽管近年来取得了显著的进展,但由于不同的设置、复杂的实现和难以复现性…...
【Unity】IBeginDragHandler、IDragHandler 和 IEndDragHandler 介绍
IBeginDragHandler、IDragHandler 和 IEndDragHandler 介绍 IBeginDragHandler、IDragHandler 和 IEndDragHandler 是 Unity 引擎中的三个接口,用于处理 UI 元素的拖放事件。这些接口通常结合使用,构成了 Unity 引擎的拖放事件系统。 IBeginDragHandler…...
杰发科技AC7801——Flash模拟EEP内存分布情况
简介 本文记录了在使用AutoChips芯片Flash模拟EEP过程中的一些理解 核心代码如下 #include <stdlib.h> #include "ac780x_sweeprom.h" #include "ac780x_debugout.h"#define SWEEPROM_SIZE (2048UL) /* Ssoftware eeprom size(Byte) */ #define TE…...
【前端知识】Node——http模块url模块的常用操作
一、创建简易Server const http require(http); const URL require(url);const HTTP_PORT 8088;const server http.createServer((req, res) > {// req:request请求对象,包含请求相关的信息;// res:response响应对象&…...
平衡二叉树 (简单易懂)
目录 一、概念 二、性质 三、插入操作 四、旋转操作 五、删除操作 六、代码实现 七、复杂度 一、概念 平衡二叉树(Balanced Binary Tree)是一种特殊的二叉搜索树(Binary Search Tree,BST),它在插入和…...
Vue.observable 是什么
Observable 翻译过来我们可以理解成可观察的 Vue.js2.6 新增 Vue.observable,让一个对象变成响应式数据。Vue 内部会用它来处理 data 函数返回的对象 。 返回的对象可以直接用于渲染函数和计算属性内,并且会在发生变更时触发相应的更新。也可以作为最小化…...
【五年创作纪念日】
机缘 我成为创作者的过程并不复杂,可以说是一个自然的发展。我是一名软件工程师,日常的工作主要是编程和解决问题。在工作的过程中,我发现有很多时候我需要查找一些特定的技术问题或者寻找一些最佳实践来解决我遇到的问题。在这个过程中&…...
数据库基础入门 — SQL排序与分页
我是南城余!阿里云开发者平台专家博士证书获得者! 欢迎关注我的博客!一同成长! 一名从事运维开发的worker,记录分享学习。 专注于AI,运维开发,windows Linux 系统领域的分享! 本…...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
基于当前项目通过npm包形式暴露公共组件
1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹,并新增内容 3.创建package文件夹...
MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...
听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
莫兰迪高级灰总结计划简约商务通用PPT模版
莫兰迪高级灰总结计划简约商务通用PPT模版,莫兰迪调色板清新简约工作汇报PPT模版,莫兰迪时尚风极简设计PPT模版,大学生毕业论文答辩PPT模版,莫兰迪配色总结计划简约商务通用PPT模版,莫兰迪商务汇报PPT模版,…...
