Vue3响应式原理简单实现

CloudCompare实战:5分钟搞定点云数据预处理(含常见格式转换技巧) 本文提供了一套基于CloudCompare的5分钟点云数据预处理实战指南。文章详细讲解了如何利用这款开源工具,快速完成点云数据的格式转换(如LAS转PLY)、统计离群值降噪、体素网格下采样以及交互式裁剪等核心操作,帮助用户高效清理和规整杂乱数据,为后续分析建模奠定基础。 阅读详情

背景

首先用一个例子来解释什么是响应式。

  1. 设置变量a为1;
  2. 设置变量b为a和2之和;
  3. 当修改a的值,b的值也会随之发生改变。

初步实现

let a = 1
let b = a + 2
a = 3 // b 为 3
a = 4 // b 为 3 

上述代码显然无法满足例子中的第三点,即b随a的变化而变化。原因很简单,JS代码是从上往下执行的。a的赋值操作无法通知上一行的b = a + 2。 如果一定要希望b及时能够响应a的变化,可以在每次a的赋值操作之后紧跟b = a + 2

简单代码的改进

let a = 1
let b = undefined
b = a + 2
// ...
a = 3
b = a + 2
// ...
a = 4
b = a + 2 

方便起见,这里将b = a + 2包在一个函数里。

let a = 1
let b = undefined
function foo() {
   b = a + 2
}
foo()
// ...
a = 3
foo()
// ...
a = 4
foo() 

但这里有一个问题,就是a的赋值操作必须手工紧跟这个foo函数的执行。 那么,是否有一个自动的方式来处理这个依赖关系呢?

Proxy对象

ES6里有一个Proxy,可以对对象属性的get/set操作进行拦截处理。 如果要将Proxy的这个功能运用到这里,需要将a包装成一个对象。

let a = 1
let b = undefined
let obj_a = {a} // 将a包装成对象
let proxy_a = new Proxy(obj_a, {
    get(target, property) {
       return target[property]
    },
    set(target, property, value) {
        target[property] = value
        foo() // 拦截set操作,执行foo函数
        return true
    }
})
function foo() {
    b = proxy_a.a + 2
}

foo()
// ...
proxy_a.a = 3 // b 为 5
// ...
proxy_a.a = 4 // b 为 6 
  • 首先,将a封装成目标对象obj_a,用Proxy对obj_a进行代理,返回的对象proxy_a为目标对象obj_a的代理对象;
  • 其次,因为对obj_a的set操作进行拦截调用foo函数,因此proxy_a的属性赋值操作,会实时的运行foo函数,这样就实时更新b值。
  • 只有对proxy_a的属性赋值才会自动调用foo函数,如果是对obj_a的属性赋值,或者直接对a赋值,则不会自动调用foo函数。

为了简化后续分析,我们将上面的问题进行进一步抽象和简化:

  • 因为这里重点关注的是响应式机制的实现,而Proxy的输入又只能适用于对象,因此文章后面部分我们只考虑对象类型的参数(因为基本类型也可以通过简单封装,改造成对象)。
  • 另外,b存在的意义在于观察程序是否能够响应proxy_a.a的变化,因此用一个console.log(proxy_a.a)也能购代替b的作用,而且还少一个变量。

可以将代码改成如下:

let obj_a = {a}
let proxy_a = new Proxy(obj_a, {
    get(target, property) {
       return target[property]
    },
    set(target, property, value) {
        target[property] = value
        foo()
        return true
    }
})
functon foo() {
    console.log('foo ', proxy_a.a)
} 

只要在每次proxy_a.a赋值,看下console.log输出的值是否也有响应变化,就能判断响应式机制是否正确实现了。

多个类似的foo函数的情况

前面的例子中正好只有一个foo函数,且这个foo函数正好用到了proxy_a.a,因此我们在set操作的时候可以精准的知道需要调用的哪个函数和函数名。 但如果是如下情况呢?

let obj_a = {a:1}
let proxy_a = new Proxy(obj_a, {
    get(target, property) {
       return target[property]
    },
    set(target, property, value) {
        target[property] = value
        foo() // 这里调用的是foo,而不是foo1还foo2,原因是什么?
        return true
    }
})
function foo() {
    console.log('foo ', proxy_a.a)
}
function foo1() {
    console.log('foo1')
}
function foo2() {
    console.log('foo2', proxy_a.a)
}
..... 

这里有多个类似的foo函数,有些和proxy_a有关,有些又没有关系。如果我们想事前就实现一个通用的proxy_a,在定义proxy_a的set操作的时候,如何知道该调用哪个函数呢?

一个有效的实现:

  • 首先运行每个foo函数,运行过程中检查是否有用到proxy_a的get方法;
  • 如果有的话,就将当前foo函数和当前的代理对象proxy_a的关系记录下来;
  • 后续如果有用到proxy_a的set方法时,再从这个对应关系获得相关联的foo函数,并依次执行。
let obj_a ={a: 1}
let set = new Set() // 保存和proxy_a有关联的函数变量
let activeFunc = undefined // 于记录当前运行的是哪个函数变量

let foo = function() {
    activeFunc = foo
    console.log('foo =', proxy_a.a)
    activeFunc = undefined
}
let foo1 = function() {
    activeFunc = foo1
    console.log('foo1')
    activeFunc = undefined
}
let foo2 = function() {
    activeFunc = foo2
    console.log('foo2 =', proxy_a.a)
    activeFunc = undefined
}

let proxy_a = new Proxy(obj_a, {
    get(target, property) {
        if(activeFunc) {
          set.add(activeFunc)
        }
        return target[property]
    },
    set(target, property, value) {
        for(let item of set) {
            item()
        }
        target[property] = value
        return true
    }
})

foo()
foo1()
foo2()

//....
proxy_a.a = 3
// ...
proxy_a.a = 4 
  • set保存和proxy_a有关联的函数变量;
  • activeFunc用于记录当前运行的是哪个函数;
  • 如果当前运行foo函数中,存在proxy_a.a,那么就会进入到get拦截器,将当前的函数变量添加到Set集合;
  • 运行完全部的foo函数,Set集合保存了所有和proxy_a.a有关系的函数变量;
  • 后续在给proxy_a.a赋值的时候,进入到set拦截器,将Set集合中保存的函数逐个执行。

总结

以上就是Vue3响应式实现的思路原型。我们总结下:

  • Vue3的响应式处理的是对象,我们称为目标对象;如果不是对象,可以通过处理,封装成一个对象;
  • 利用Proxy,从目标对象生成一个代理对象,代理对象的属性读写操作可以进行拦截预处理;
  • 将响应式关联逻辑封装到函数中,且响应式逻辑中的目标对象须替换为代理对象;
  • 程序运行的同时也同时运行上述封装的函数,并收集和代理对象get操作有关的函数变量,保存到一个Set集合中;
  • 执行完毕之后,如有对代理对象的属性赋值操作,则会触发Set集合中的函数变量依次执行,从而完成响应式流程。
AI大模型探索之路-认知篇1-全景透视:揭秘AIGC技术的进化之路 随着人工智能技术的突飞猛进,内容创作方式的发生了革命性的转变;从早期专业人员主导的内容生产,到现如今生成式人工智(AIGC)能创作时代;本篇文章主要讲解AIGC技术的演变历程。 阅读详情

相关推荐

浅谈功放PA的VBW

摘要:VBW(视频带宽)反映功放的宽带非线性特性和记忆效应,影响数字预失真(DPD)校正能力。其成因是功放管寄生参数(如Cshunt和Leff)形成低频并联谐振,导致供电臂阻抗增大,引发电压波动和记忆效应。测试方法包括双音IM3/IM5测试(以两侧IM3差≥3dB定义VBW)和魔T测试(通过S21曲线测量谐振频率)。改善措施主要是减小Leff,如采用双电源平衡馈电。VBW指标要求通常为魔T测试结果大于3倍信号带宽,以确保功放线性度。

weixin_49761275的博客 1574

Vue export、import、export default详解

Vue export、import、export default详解 一.export 一个模块就是一个独立的文件。该文件内部的所有变量,外部无法获取。如果你希望外部能够读取模块内部的某个变量,就必须使用export关键字输出该变量。 用法 //输出变量用法1 export var firstName = 'Michael'; export var lastName = 'Jackson'; export var year = 1958; //输出变量用法2 var firstName = 'Michae

qq_40891322的博客 1万+

Altium Designer差分走线实战:从规则设置到阻抗匹配的完整流程

本文详细讲解了在Altium Designer中进行差分走线的完整实战流程,涵盖从原理图定义差分对、PCB布局管理、关键设计规则设置,到利用阻抗计算工具确定线宽与间距,以及布线技巧与等长处理等核心步骤。文章旨在帮助工程师掌握高速PCB设计中差分信号传输的关键技术,确保信号完整性并实现精确的阻抗匹配。

weixin_29163857的博客 259

vue3中用 let a= b赋值会改变b的值

vue3中用 let a= b赋值会改变b的值

susu1083018911的博客 853

创建动态代理对象bean,并动态注入到spring容器中

使用过Mybatis的同学,应该都知道,我们只需要编写mybatis对应的接口和mapper XML文件即可,并不需要手动编写mapper接口的实现。这里mybatis就用到了JDK动态代理,并且将生成的接口代理对象动态注入到Spring容器中。 这里涉及到几个问题。也许有同学会有疑问,我们直接编写好类,加入@Component等注解不是可以注入了吗?或者在配置类(@Configuration)...

lichuangcsdn的博客 3万+

【电力电子控制】基于强化学习的单相逆变器并网电流控制

本文将尝试以 DQN(Deep Q-Network)为例,设计并训练一个面向单相逆变器的智能控制器,实现对并网电流的精准调节。

weixin_62596197的博客 463

vue学习

一、全局注册和局部注册 <div id='app'></div> <script> const Bar = { template: ` <h1>im 局部 bar</h1> ` } Vue.component('Foo', { components: { Bar }, template: ` <h1>im Foo <Bar></Bar> </h1&g

Joy_Huu的博客 271

使用MATLAB求解二维顶盖驱动流问题的详细代码和说明

本文介绍了使用MATLAB求解二维顶盖驱动流问题的涡量-流函数方法。代码采用129×129网格,雷诺数Re=1000,通过迭代求解Navier-Stokes方程,包含流函数方程和涡量输运方程的离散求解。程序实现了边界条件处理、收敛性检查,并提供丰富后处理功能:流线图、涡量分布图、中心线速度曲线、矢量图和三维涡量可视化。计算结果可与Ghia等(1982)的经典数据进行验证。该代码完整展示了CFD问题的数值求解流程,包括参数设置、主循环计算和多种结果呈现方式,适用于流体力学教学和科研验证。

AI的内部世界的博客 227

Vue学习笔记整理

一、Vue2 Vue.js(读音 /vjuː/, 类似于 view) 是一套构建用户界面的 渐进式框架。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。Vue.js是一个MVVM模式的框架。 1、vue2需掌握的几方面 网络通信 : axios(不属于Vue框架,单独的一套前端通信框架,负责与服务器交互。) 页面跳转 : vue-router 状态管理:vuex Vue-UI : ICE , Element UI css:SASS(基于Ruby)、LESS(基于Node

w_wu_zx的博客 556

090、Sensor上电时序与帧同步的驱动级实现——以索尼IMX766为例的AVDD/DVDD/IOVDD时序调优

摘要: 本文以索尼IMX766传感器为例,深入探讨了传感器上电时序与帧同步的驱动级实现问题。通过分析某车载项目量产中的高温黑屏故障,揭示了AVDD/DVDD/IOVDD时序偏差导致传感器内部状态机异常的根源。文章详细解读了IMX766三路电源的时序约束(如AVDD与DVDD需在1ms内同步至90%),并提供了驱动代码级实现方案,包括电源使能顺序、延时控制及帧同步配置。针对多摄同步场景,强调了曝光时间寄存器写入一致性的重要性。最后结合产线问题定位经验,提出通过示波器抓取电源波形验证时序合规性的方法。全文聚焦硬

zzfmlxs的博客 260

SAP 中配置权限职责菜单并分配给用户的核心流程是:用PFCG 创建 / 维护角色(含菜单、事务码、权限)→ 生成权限参数文件 → 通过 SU01/SU10 将角色分配给用户

SAP权限配置核心流程:1)通过PFCG创建角色,配置菜单事务码及权限对象;2)生成权限参数文件;3)用SU01/SU10分配角色给用户。关键步骤包括:在PFCG中维护菜单结构、设置权限字段值、生成Profile,通过用户比较验证权限。批量分配可用SU10,特殊需求可创建复合角色或自定义权限对象。常见问题需检查权限缺失(SU53)、菜单分配及组织级别设置。流程简化为:创建角色→配置权限→分配用户→验证生效。

金牌架构师 1275

Vue3废除了$set,如何向对象中添加响应式的属性

vue3 如何添加响应式属性

c327127960的博客 7803

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Vue3.0响应式原理(Reactive)简单版实现

Vue3.0响应式原理(Reactive)简单版实现 下班回家,抽空写了这篇一直想写的关于vue3的reactive的文章,我们都知道在vue2中对于数据的响应式是通过Object.defineProperty来实现的,但是这个方法对于数组是无法监听的,而且对于复杂结构的对象,需要深层次的遍历对象的属性来进行监听,十分耗费性能。相比之下proxy拥有更强大的功能。 下面我简单介绍一下proxy属性的优势 Proxy可以直接监听对象而非属性 Proxy可以直接监听数组的变化 Proxy有13中拦截方法,功能

Xinshenbaba的博客 585

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Vue2、Vue3响应式实现方案原理模拟,只是简单的模拟

Vue2 / Vue3响应式实现方案原理模拟,只是简单的模拟 ||来源:尚硅谷前端vue视频,它家的视频巨好 「模仿」Vue2响应式实现方案 ⭕️ 原理:使用defineProperty() let person = { name:'ulrich' } let p = {} Object.defineProperty(p,'name',{ configurable: true, get(){ return person.name }, set(value){ consol

ChuanyangChen的博客 338

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

vue3的响应式原理简单实现

【代码】vue3的响应式原理简单实现。

qq_45331969的博客 818

Vue3源码【一】—— ref&reactive响应式原理及简单实现

本文深入剖析了Vue3中ref和reactive的工作机制及背后的响应式原理。文章首先揭示了ref是如何将一个普通值封装成响应式的,并返回一个可访问该值的响应式对象。接着,详细讨论了reactive如何使用Proxy来实现对象的响应式转换,使其所有属性的变化都能被Vue3精确捕捉。文中进一步探讨了Vue3响应式系统的内核,即依赖追踪和派发更新机制,展示了它们如何确保界面与状态的一致性。

共勉 3624

说说 vue3 中的响应式设计原理,用js文件简单模拟实现vue3中的响应式

响应式数据指的是当数据发生变化后,能够自动触发某些副作用的执行,从而达到某些目的。在应用中,这通常意味着当数据改变时,所有依赖于该数据的地方都会自动更新。这种响应式机制特别适用于动态内容更新、表单验证和处理、数据驱动的交互等场景。众所周知,Vue通过Object.defineProperty或Proxy等方式来劫持数据对象的getter和setter,从而能够在数据变化时通知依赖它的代码部分进行更新。那么今天我们就来用js文件来简单模拟一下vue3实现的响应式数据。

自然 醒的博客 1041

Vue3响应式原理实现(简单手写)

//设置缓存 let toProxy = new WeakMap() let toRaw = new WeakMap() //proxy配置 const baseHander = { get(target, key){ const res = Reflect.get(target, key) // 收集依赖 track(target, key) // 递归寻找 return typeof res=='object' ? reactive(res) : res

起风了 475

Vue3 响应式原理详解

Vue 3 的响应式系统基于 Proxy对象,它允许 Vue 拦截对象的读写操作,并在这些操作发生时执行特定的逻辑。与 Vue 2 中基于的响应式实现相比,Proxy提供了更强大的功能,能够监听更多类型的操作(如属性的添加和删除),并且能够在性能上获得提升。reactive:创建一个深层响应式对象,可以跟踪所有嵌套属性的变化。ref:用于将基本类型的数据变成响应式,或者用来封装引用类型的对象。computed:用于定义计算属性,可以根据其他响应式数据动态计算值。effect。

xiaowu5705的博客 2851

vue2和vue3响应式原理

vue2和vue3响应式原理 文章目录vue2和vue3响应式原理一、问题分析?二、Object.defineProperty使用方法:6个配置项(4个酱油,2个重要)三、实现一个简单的响应式代码四、观察者模式五、实现一个简易的vue六、vue3实现响应式七、vue2和vue3实现响应式的区别八、浅淡vue2为什么不能直接监控数组的操作九、自我总结 一、问题分析? 1.如何实现数据变了,视图也跟着变?核心是:如何知道对象的属性值被修改了? 2.如何实现一个数据变量,多出视图跟着变? 3.如何保证视图改变

qq_52275987的博客 734

vue3响应式数据原理

Vue 3 响应式系统改用 Proxy 替代 Vue 2 的 Object.defineProperty,性能更优且功能更强。核心原理是通过 Proxy 拦截对象操作,结合 Reflect 执行默认行为,并利用 effect 函数追踪依赖、Dep 类管理依赖。当属性被访问时自动收集依赖,修改时自动触发更新。相比 Vue 2,Proxy 能监听整个对象而无需递归遍历属性,支持更多操作类型,代码也更简洁高效。

这个人很懒~ 692

【JavaScript_1】Vue2中Object.defineProperty响应式实现原理

Vue中的响应式是指,data()中的数据一旦发生了改变,页面就会自动进行相应的改变,给予用户一个网页在随着用户操作进行“响应式”更新的感受。 所以需要解决的就是,如何监听到数据的改变呢?因为这样在能在数据改变的一瞬间去做出一些更新页面的操作呀,答案就是用Object.defineProperty()来解决。 Object.defineProperty()是JavaScript中提供的一个接口,用来给一个对象新增一个属性并定义属性描述符,或是对对象的一个已有属性更改值、定义属性描述符,可以接收“对象,属性名

ryling_的博客 1093

彻底理解Vue数据响应式原理

彻底理解Vue数据响应式原理

qq_42880714的博客 3595

面试题之vue的响应式

为了应对面试而进行的学习记录,可能不够有深度甚至有错误,还请各位谅解,并不吝赐教,共同进步。我们已经大致将vue实现响应式简单的模拟了一下了,其中我们可以发现对于对象新增属性和删除属性我们是无法监听到的,所以vue中有其他的专门方法来完成。对于数组,我们就需要重新修改原型来实现监听。在vue2中对于深度监听是一次不断循环来完成的,如果数据层级多,速度会变得慢。vue3使用proxy后速度会有提高,还支持检测属性的新增和删除,以及监听数组,后续学习后更新文章进行记录。

xia_zai_ya的博客 1254

Vue 3 的响应式原理

监控数据访问get):记录谁在关注这个数据。监控数据修改set):通知所有关注者更新。自动化管理依赖:开发者只需关注数据变化,视图自动同步。通过Proxy的强大能力,Vue 3 解决了 Vue 2 的诸多限制(如数组和新增属性的响应问题),同时提升了性能和开发体验。

weixin_48953950的博客 1367

vue3 中的 ref、reactive和v3响应式原理

而reactive是通过ES6中的Proxy实现数据劫持,并通过Reflect去操作源对象内部的数据。不管数据有多深,多复杂,reactive都可以进行处理,定义的响应式数据是深层次的。ref可可以定义对象(数组类型),但是内部还是借助reactive去实现响应式效果。去拦截对象中任意属性的变化,包括属性的读写、属性的添加、和属性的删除等等,我们把reactive包裹的对称为源对象,返回的为代理对象(第一个参数是要代理的源对象,第二个参数是一个配置对象。Proxy的实例对象,简称proxy对象。

shmily的博客 1712
上一篇: vue3插槽学习——起步(一)
下一篇: vue-infinite-scroll 源码阅读&排坑
梅花十三儿
博客等级 码龄5年 1038粉丝 444原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值