Vue响应式的原理

news2024/11/27 18:40:39

一. Vue响应式原理的核心概念

1. Vue响应式原理基于以下核心概念:

① 响应式对象:Vue使用Object.defineProperty()来  reactive(反应)对象中的属性,使其变化可以被检测。
注意:
        ★ Object.defineProperty() 是JavaScript中的一个方法,‌用于在一个对象上定义新属性或修改现有属性。‌这个方法接收三个参数:‌目标对象、‌属性名称和一个描述符对象。‌描述符对象可以包含以下属性:‌
     ☆ value:‌属性的值。‌可以是任何类型的值。‌
     ☆ writable:‌一个布尔值,‌表示属性值是否可以被改变。‌默认为false。‌
     ☆ enumerable:‌一个布尔值,‌表示属性是否可以在for...in循环或Object.keys()中被枚举。‌默认为false。‌
     ☆ configurable:‌一个布尔值,‌表示属性是否可以被删除或改变其属性描述符。‌默认为false。‌
        ★ reactive是vue.js中用于创建响应式数据的一个函数,其作用是将普通JavaScript对象转换成响应式对象,使其能自动更新视图。通过依赖关系追踪系统,当响应式数据的值发生变化时,所有依赖数据的视图组件都会自动更新,从而简化开发并优化性能。

② 依赖追踪:对每个响应式属性,维护一个依赖(Dependency)的列表,这些依赖是Watcher对象
注意
        ★ Watcher对象:是一个观察者对象,‌用于监听数据的变化执行相应的回调函数

③ 虚拟DOM:使用虚拟节点(VNode)进行高效的DOM更新
注意
        ★ 虚拟节点(‌Virtual Node,‌简称VNode)‌:是一种用JavaScript对象来描述DOM树结构的概念。‌它是Vue框架中的一个核心概念,‌用于高效地渲染和更新视图。‌虚拟节点本质上是一个普通的JS对象,‌用于描述视图的界面结构。‌

④ 事件侦听和触发:通过emit方法on方法来触发和监听事件,从而触发Watcher的重新计算和DOM的更新。
注意
        ★ emit方法是Vue实例中用来触发事件的方法,‌用于在子组件中触发一个自定义事件,‌并将数据作为参数传递给父组件,可以通过在组件中使用$emit方法来触发事件。‌
        ★ $on方法是一个用于监听自定义事件的方法允许在一个组件中监听自定义事件,‌并在事件触发时执行一个回调函数,可以实现组件之间的通信,‌尤其是当子组件需要向父组件发送信息时,能够构建更灵活和可维护的应用程序。

2. 以下是一个简化的响应式系统的例子:

注意:这个例子中,我们创建了一个简化版的Vue类,它具有响应式数据和$watch方法来观察这些数据的变化。当数据属性被设置时,它会通知依赖(Watcher)进行更新,并执行相应的回调函数。这个例子展示了Vue响应式系统的核心概念,但实际的Vue实现要复杂得多,包含更多优化和功能。 

二. Vue2和Vue3响应式原理的区别

1. Vue2的响应式原理:基于Object.defineProperty()实现的

★ Vue2通过Object.defineProperty()来实现数据的劫持,‌即对对象的属性进行拦截。‌通过getter(获取)函数setter(设置)函数来处理属性的读取和修改,‌当数据发生变化时,‌通过发布-订阅模式通知视图进行更新。‌此外,‌Vue2还通过重写数组的一系列方法来拦截数组的变更操作,‌如push、‌pop等,‌以确保数组的变更也能触发视图的更新。‌
注意
        ★ getter(获取)函数是一种用于从store中获取数据的函数,‌它类似于Vue组件中的计算属性,允许你从store中的state中提取数据,‌并且可以处理state中的数据,可以接受state作为第一个参数,‌也可以接受其他的getter函数作为第二个参数。Getter函数的结果会根据它的依赖进行缓存,‌只有当依赖发生变化时才会重新计算,这种机制在处理复杂状态逻辑时非常有用,‌因为它提供了对数据的计算和缓存机制,‌避免了不必要的重复计算。‌
        ★ setter(设置)函数是一种特殊的函数,‌用于设置对象的属性值通常与getter函数一起使用,‌它们共同构成了访问器属性(‌也称为存取器属性)‌,访问器属性包括getter和setter两部分,‌其中getter用于获取属性的值,‌而setter用于设置属性的值。‌在JavaScript中,‌可以通过Object.defineProperty()方法为对象定义getter和setter。‌当使用Object.defineProperty()为对象添加属性时,‌可以指定一个getter函数和一个(‌可选的)‌setter函数。‌当读取该属性时,‌getter函数会被调用;‌当修改该属性时,‌setter函数会被调用。‌
        ★ 具体来说,‌getter函数是一个不带参数的函数,‌它负责返回属性的值。‌而setter函数则负责设置属性的值,‌它接受一个参数,‌即要设置的新值。‌在setter函数的函数体中,‌任何的return语句都是无效的,‌因为setter函数的主要目的是修改属性的值,‌而不是返回一个新的值。‌

2. Vue3的响应式原理:基于ES6的Proxy实现的

★ Vue3引入了ES6的Proxy特性来实现数据的代理。‌通过Proxy对象来拦截对源对象的操作,‌包括属性的读取、‌设置、‌增加、‌删除等。‌当这些操作发生时,‌Vue3通过Reflect函数对源对象的属性进行操作,‌并通过定义Proxy对象的handler(操作者)来处理这些操作。‌这种方式不仅支持更多种类的数据结构,‌还提供了更灵活和强大的响应式功能。‌
注意
        ★ handler(操作者)通常指的是处理事件的函数,也就是与特定事件相关联的函数,在事件触发时被调用,‌以执行相应的操作或响应。‌在Vue实例中,‌可以通过在methods选项中定义handle函数,‌或者直接在Vue实例中定义一个匿名的handle函数来实现。‌handler函数可以接收事件对象作为参数,‌并根据需要传入其他参数。‌Vue允许在监听键盘事件时添加按键修饰符,‌以便在特定条件下调用handler函数。‌例如,可以使用@keyup.enter="submit"来监听键盘的回车键事件,‌当按下回车键时,‌调用submit函数。‌这种机制使得Vue能够灵活地处理各种用户交互事件,‌从而增强用户体验和应用程序的响应性

3. 区别

① 最主要的区别是 Vue 3 采用了 Proxproxy 来代替 Vue 2 中的 Object.defineProperty。
② Vue 3 使用 Proxy 替代了 Vue 2 中的 Object.defineProperty 主要有以下原因
        ★ Object.defineProperty 不能监听到属性的增加和删除,而 Proxy 可以。
        ★ Object.defineProperty 不能监听数组的索引和长度变化,而 Proxy 可以。
        ★ Proxy 可以直接监听整个对象不需要像 Vue 2 一样递归遍历每个属性
        ★ Proxy 返回的是一个新对象,我们可以只操作新对象达到间接修改原对象的目的,而 Vue 2 中,我们需要使用 Vue.set/vm.$set 这样的 API 来修改响应式对象,这种方式对用户不够友好。
③ 总的来说,Vue3的响应式系统相比Vue2更加现代化和灵活,‌能够更好地支持复杂的数据结构和操作。‌这种改进使得Vue3在处理大型应用和复杂状态管理时更加高效和便捷。

4. Vue 2 响应式系统示例:

 

5. Vue 3 响应式系统示例:

注意:在 Vue 3 中,我们使用 reactive (反应)函数来创建响应式对象,而在 Vue 2 中,我们使用 data(数据) 选项来创建响应式对象。另外,Vue 3 引入了 Composition API(组合式API,它允许我们更灵活地组合和重用代码。在 Vue 2 中,我们通常使用 mixins (混入)或者高阶组件来实现类似的功能,但是这些方法都有各自的问题和限制。
        ★ reactive(反应)函数是一个用于创建响应式对象的函数简单来说,‌reactive函数的作用是将一个普通的JavaScript对象转换成Vue的响应式对象,‌使得当该对象的属性发生变化时,‌Vue能够检测到这种变化并自动更新视图,这是Vue 3中实现数据驱动视图更新的重要机制之一。
        ★ data(数据)选项是一个特殊的配置项,‌用于存储组件中的数据在Vue.js中,‌data属性是组件的一个核心配置选项,‌它用于定义组件的状态。‌这个属性可以是一个对象,‌也可以是一个函数,‌具体取决于组件的使用场景。‌当data以对象的形式出现时,‌它通常用于根实例或非复用组件中,‌直接提供一个对象字面量来定义数据。‌这种方式下,‌data属性是一个普通的对象,‌直接作为组件实例的一个属性,‌通过对象属性初始化数据。‌这种方式的好处是语法简洁直观,‌方便管理多个属性,‌但缺点是所有组件实例可能共享同一个数据对象,‌导致数据污染的风险。
        ★ Composition API(组合式API是一种新的API集合,‌它允许开发者使用函数而不是声明选项的方式来书写Vue组件。‌这种API集合旨在提供一种更灵活、‌可重用的代码组织方式,‌以实现代码的共享和重用。‌Composition API是Vue 3.0引入的一个重要特性,‌它提供了一系列函数和工具,‌使得开发者能够更灵活地组织和共享代码逻辑,‌而无需依赖于传统的Vue实例。‌
        ★ mixins(混入)是一种分发Vue组件中可复用功能的非常灵活的方式,允许组件共享方法和属性,‌通过将公用的功能以对象的方式传入mixins选项中,‌当组件使用mixins对象时,‌所有mixins对象的选项都将被扩展到该组件本身的选项中。‌这意味着,‌如果多个组件需要共享某些功能,‌如数据、‌计算属性、‌方法等,‌可以通过定义一个mixins对象来实现,‌然后在需要的组件中使用这个mixins对象,‌从而避免代码重复和冗余,‌提高代码的重用性和可维护性。‌

 

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

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

相关文章

Python字符串处理技巧:一个小技巧竟然能省下你一半时间!

获取Pyhon及副业知识,关注公众号【软件测试圈】 效率翻倍的秘密:Python字符串操作的5个惊人技巧 在Python编程中,字符串处理在数据分析、Web开发、自动化脚本等多个领域都有广泛应用。Python提供了一系列强大的字符串处理函数,能够…

蚓链数字化生态平台:构建城市智能商业,引领协同发展新潮流

​在当今数字化飞速发展的时代,城市商业的运行模式正在经历着数字化变革。蚓链数字化生态平台应运而生,以其强大的功能和创新的理念,成为构建城市智能商业枢纽中心的关键力量,推动着平台互通、业务贯通、管理协同的全新发展格局。…

MySQL数据库-索引和视图

一、视图 1.什么是视图 MySQL中的视图(view)是一种虚拟表,其内容由查询定义,视图本身并不包含数据。视图看起来和真实的表完全相同,但其中的数据来自定义视图时用到的基本表,并且在打开视图时动态生成&am…

【JavaWeb项目】——外卖订餐系统之登入、登入后显示餐品信息、用户注册、注销部分

🎼个人主页:【Y小夜】 😎作者简介:一位双非学校的大二学生,编程爱好者, 专注于基础和实战分享,欢迎私信咨询! 🎆入门专栏:🎇【MySQL&#xff0…

什么是内网ip地址?如何查询电脑内网ip地址

在数字化时代,互联网已经成为我们日常生活和工作中不可或缺的一部分。无论是家庭网络还是企业办公环境,每台接入网络的设备都需要一个独特的标识来区分彼此,这个标识就是IP地址。IP地址全称为“互联网协议地址”,是设备在网络中的…

springboot整合junit-用于测试用例

package impl;public interface BookDao {public void save(); }第一步:打开软件,点击file,点击new 然后选择module,在右侧选择springboot 第二步:选择配置和JDK以及java版本 ①选择maven类型 ②选择JDK1.8版本 ③选…

react中路由懒加载

// 1.引入方法,用于创建路由实例 // createBrowserRouter是用于创建history模式 // createHashRouter是用于创建hash模式 // 路由模式的切换只需要更改创建路由实例的方法就行了,其他地方不需要更改 import { createBrowserRouter,createHashRouter } fr…

deployment

一.deployment rc和rs控制器都是控制pod的副本数量的,但是,他们两个有个缺点,就是在部署新版本pod或者回滚代码的时候,需要先apply资源清单,然后再删除现有pod,通过资源控制,重新拉取新的pod来实…

【Vue3复习】Vite创建项目报错解决

报错: Cannot find package ‘vite’ 出错原因分析 使用命令npm create vuelatest创建项目时,没有按顺序执行以下提示命令 解决 依序执行这三条指令 注意 如果没有执行 npm install 这条指令,直接用VS Code打开项目时,env.d.…

职场英语培训柯桥成人学外语|邮件里别乱用“Dear”,老外才不会这么写!

写邮件是职场上的必修课,而一封好的英语邮件应当从适合的称呼开始。 说到称呼,你的脑子里是不是冒出了一个单词“Dear” 从小我们就被教育写英语作文时,开头先来个Dear,结尾写个Sincerely,简直不要太顺手~ 然&#xff…

HDU1071——The area,HDU1072——Nightmare,HDU1073——Online Judge

目录 HDU1071——The area 题目描述 运行代码 代码思路 HDU1072——Nightmare 题目描述 运行代码 代码思路 HDU1073——Online Judge 题目描述 运行代码 代码思路 HDU1071——The area 题目描述 Problem - 1071 运行代码 #include <iostream> #include &…

CloudWeGo新手教程视频:手把手教你从0到1打造电商商城微服务demo

概要 Gomall 电商项目视频教程&#xff0c;由 CloudWeGo 技术社区出品&#xff0c;旨在帮助开发者掌握 Go 语言项目开发和微服务架构。教程通过演示 CloudWeGo 项目中的 Kitex 和 Hertz 框架&#xff0c;引导 Go 初学者学习常见的技术和开源中间件。 观看教程请访问&#xff…

高效灵活 | 前端利器 Vue.js 是一个构建用户界面的渐进式框架。

Vue.js 是一个构建用户界面的渐进式框架。 官网&#xff1a;https://cn.vuejs.org/ 基本特性 数据驱动&#xff1a;通过响应式机制&#xff0c;实现数据的变化自动触发视图的更新。 组件化架构&#xff1a;高度可复用的组件结构&#xff0c;提升代码组织性和可维护性。 虚拟…

爬虫-实战爬取虎扑ACG帖子

要求如下: 爬取虎扑步行街 ACG 版面的数据,要求使用多线程来并发爬取。范围是第一页的所有帖子,每个帖子包含标题、主题内容和第一页的所有回复内容。最后打印出爬到的所有帖子的标题。 网址是:ACG圈 - 虎扑社区。 针对上面的要求,我们进行分析: 首先是要使用多线程范…

YOLO5项目目录最强解析

YOLO5项目目录解析 YOLOv5 项目目录下的文件和目录的结构&#xff0c;以下是对每个目录和文件的解释&#xff1a; 目录 &#x1f4c1; .github: 存放 GitHub 相关配置和文件&#xff0c;如 GitHub Actions 工作流文件、Issue 模板等&#xff0c;用于自动化构建和持续集成等功…

Java编写SIP协议

1、编写Server代码 package com.genersoft.iot.vmp.sip; import javax.sip.*; import javax.sip.message.*; import javax.sip.header.*; import java.util.*;public class SimpleSipServer implements SipListener {private SipFactory sipFactory;private SipStack sipStack…

神经网络的参数初始化【PyTorch】

文章目录 1、常见初始化方法2、代码2.1、导包&#xff1a;2.2、均匀分布随机初始化2.3、固定初始化2.4、全0初始化2.5、全1初始化2.6、正态分布随机初始化2.7、kaiming 初始化2.8、xavier 初始化2.9、完整代码 3、小节 &#x1f343;作者介绍&#xff1a;双非本科大三网络工程专…

哨兵Sentinel-2一些有趣的示例

每天我们都会观察周围的世界。在许多情况下&#xff0c;我们认为我们所看到的事物是不言而喻的&#xff0c;它们只是我们所认为的那样。其他时候&#xff0c;我们会更仔细地分析和询问那些看起来不太熟悉的事物。有时&#xff0c;仅仅改变我们的视觉视角就能提供额外的启发和启…

html实现我的博客文章相册源码

文章目录 1.设计来源1.1 相册界面1.2 相册详细界面1.3 文章界面1.4 文章详细界面1.5 关于我1.6 联系我 2.效果和源码2.1 动态效果2.2 源代码 源码下载万套模板&#xff0c;程序开发&#xff0c;在线开发&#xff0c;在线沟通 作者&#xff1a;xcLeigh 文章地址&#xff1a;http…

轻松上手MYSQL:JSON函数实现高效数据查询与操作

&#x1f308; 个人主页&#xff1a;danci_ &#x1f525; 系列专栏&#xff1a;《设计模式》《MYSQL》 &#x1f4aa;&#x1f3fb; 制定明确可量化的目标&#xff0c;坚持默默的做事。 ✨欢迎加入探索MYSQL字符串函数之旅✨ &#x1f44b; 大家好&#xff01;文本学习和探…