Vue 3 响应式原理是什么Proxy、ref 和 reactive 有什么区别Vue 3 的 reactive 为对象创建响应式代理。依赖执行时读取属性系统记录这段逻辑依赖哪个属性属性改变后再通知相关依赖更新。Proxy 负责拦截操作依赖收集和触发机制负责建立对应关系。不是任意一次读取都会登记也不是每次修改都让整页立即重新渲染组件更新还会经过调度。ref 则用带 .value 的包装让基本类型和对象都能作为响应式值使用。reactive 更适合直接组织对象属性ref 也方便整体替换值。解构 reactive 中的基本类型属性会得到当时的普通值后续访问不再经过原代理。需要保留与原属性的连接时可以使用 toRef 或 toRefs。对象属性的解构要另外看它是否仍然指向响应式对象。拦截读写怎样变成更新页面先建立一个具体关系假设页面显示state.count。组件渲染时会读取这个属性。Vue 在这一轮渲染逻辑执行期间能够知道当前有哪些属性被使用。于是它记下来“这个渲染逻辑需要 count。”以后 count 改变就能找到需要重新执行的逻辑。如果另一段逻辑只读 name它不应该仅仅因为 count 改了就成为 count 的直接依赖。这就是“依赖收集”要解决的事情。只说 Proxy 可以拦截还没有说明页面与属性怎样建立关系。读取时记录修改时通知可以把主要过程理解成三步某段需要跟踪的逻辑开始执行成为当前活跃的依赖。它读取代理属性系统记录对象、属性与依赖之间的关系。属性改变后系统找到相关依赖触发或调度它们重新执行。Vue 官方响应式原理给出了 track 与 trigger 的教学示意。实际实现还需要处理嵌套执行、过期依赖清理、数组与集合等情况不能拿几行伪代码当完整源码。如果代码只在普通函数里随手读了一次属性而没有处于依赖收集的执行过程中就不能认为这个函数以后会自动再次运行。reactive 和 ref不只是对象与数字的区别reactive 返回对象代理。对属性读写才能经过代理的拦截。如果还拿原始对象直接修改就绕开了这条入口。ref 返回一个带.value的容器对这个值的读取与修改也能被跟踪。它可以保存数字也可以保存对象对象值通常会经过响应式转换shallowRef 等 API 则有不同约定。因此“对象一定用 reactive数字一定用 ref”只是一种简化习惯不是能力边界。如果经常需要替换整个值比如请求完成后把结果列表整体换掉ref 的.value 新值往往比较直接。reactive 则更适合保留一个代理对象修改其中属性。解构后为什么有时不更新看一个 Vue 3 局部示例import{reactive,toRef}fromvue;conststatereactive({count:0});const{count}state;// 当时读出的普通数字constlinkedCounttoRef(state,count);state.count2;console.log(count);// 0console.log(linkedCount.value);// 2linkedCount.value3;console.log(state.count);// 3普通数字被取出来以后变量与原属性已经不是同一个可追踪入口。toRef 则保留了指向该属性的连接。不过如果解构的是一个响应式对象引用继续修改那个对象的属性仍然可能触发响应式。问题是“变量绑定是否与原属性相连”不能简单背成“只要解构就彻底没响应式”。这里的代码针对 Vue不提供不同语言里名为 Proxy 的对象来冒充同一机制。数据改变了DOM 为什么还没立即改变响应式通知和 DOM 已更新是两个时间点。Vue 通常把组件更新放进调度队列合并同一轮中的多个变化避免每修改一个值就立刻重复更新。需要在更新后读取 DOM可以使用 nextTick 等待相应更新完成。computed 则是在响应式系统上建立派生值。它会跟踪所读取的依赖并按缓存与求值规则工作不是普通函数换了一个名字。讲到这里才能从数据读写一路解释到组件更新而不是只回答“Vue 3 用了 Proxy”。面试官继续追问Proxy 能直接代理数字吗不能直接以基本类型作为 Proxy 的目标对象。ref 提供了包装入口使数字等值也能进入响应式系统。reactive 返回值等于原对象吗引用身份不同。代理虽然表现得像原对象但proxy original通常为 false。项目中最好统一通过代理操作避免混用导致追踪问题。模板里为什么常常不用写 .valueVue 模板提供了 ref 解包规则但规则有具体适用条件。JavaScript 代码中操作 ref通常仍然使用 .value不能把模板便利理解成容器不存在了。面试速记卡Proxy拦截操作不独自完成整套响应式。读取阶段在依赖执行时记录对象、属性与依赖的关系。修改阶段通知相关依赖组件更新还要经过调度。ref 与 reactive容器值和对象代理都有适合的组织方式。解构边界基本类型会断开属性连接可用 toRef 保留连接。我是程序员Sunday。本文收录于 sunday面试指南原文与配图可继续阅读。