如何构建一个响应式系统,类似于Vue 3的Reactivity?

答案:通过 Proxy 拦截 get/set,结合 WeakMap 存储依赖,利用 effect 收集并触发更新,实现响应式系统。具体为 reactive 创建代理对象,track 收集 activeEffect 依赖,trigger 时遍历执行,从而在数据变化时自动更新副作用函数,核心机制与 Vue 3 一致。

如何构建一个响应式系统,类似于vue 3的reactivity?

要构建一个响应式系统,类似 Vue 3 的 Reactive 系统,核心是利用 JavaScript 的 Proxy 捕获对象属性的读取和修改,并在变化时自动触发依赖更新。Vue 3 使用了 Proxy + Reflect + 依赖收集与触发机制来实现高效响应式。下面带你一步步实现一个简化但原理一致的响应式系统。

1. 响应式基础:使用 Proxy 实现 reactive

通过 Proxy 拦截对象的 get 和 set 操作,我们可以在访问属性时收集依赖,在修改属性时触发更新。

function reactive(target) {
  if (typeof target !== ‘object’ || target === null) return target;

  return new Proxy(target, {
    get(obj, key, receiver) {
      // 收集依赖
      track(obj, key);
      return Reflect.get(obj, key, receiver);
    },
    set(obj, key, value, receiver) {
      const result = Reflect.set(obj, key, value, receiver);
      // 触发依赖
      trigger(obj, key);
      return result;
    }
  });
}

2. 依赖收集与触发:track 和 trigger

我们需要一个地方存储“谁在依赖某个对象的哪个属性”。可以使用 WeakMap 存储对象结构,避免内存泄漏。

// 存储依赖关系:target -> key -> effects
const targetMap = new WeakMap();

function track(target, key) {
  if (!activeEffect) return; // 没有正在运行的副作用函数,不收集
  let depsMap = targetMap.get(target);
  if (!depsMap) {
    targetMap.set(target, (depsMap = new Map()));
  }
  let dep = depsMap.get(key);
  if (!dep) {
    depsMap.set(key, (dep = new Set()));
  }
  dep.add(activeEffect);
}

function trigger(target, key) {
  const depsMap = targetMap.get(target);
  if (!depsMap) return;
  const dep = depsMap.get(key);
  if (dep) {
    dep.forEach(effect => effect());
  }
}

3. 副作用函数:effect

effect 是响应式系统的执行单元。它包装一个函数,在执行时会触发 getter,从而被收集为依赖。

立即学习“前端免费学习笔记(深入)”;

let activeEffect = null;

function effect(fn) {
  const effectFn = () => {
    try {
      activeEffect = effectFn;
      return fn();
    } finally {
      activeEffect = null;
    }
  };
  effectFn(); // 立即执行一次以触发依赖收集
  return effectFn;
}

4. 实际使用示例

将以上模块组合起来,就可以实现一个简单的响应式系统。

const state = reactive({ count: 0 });

effect(() => {
  console.log(‘count is:’, state.count);
});

state.count++; // 输出: count is: 1
state.count++; // 输出: count is: 2

每次 state.count 被修改,都会触发所有依赖它的 effect 函数重新执行。

基本上就这些。虽然这只是一个简化版本,但它涵盖了 Vue 3 响应式系统的核心思想:Proxy 拦截、依赖收集(track)、触发更新(trigger)以及副作用调度(effect)。真正生产级系统还会加入调度器、嵌套对象处理、数组监听、cleanup、computed 等优化,但底层逻辑一致。

以上就是如何构建一个响应式系统,类似于Vue 3的Reactivity?的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1525705.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月20日 17:54:04
下一篇 2025年12月20日 17:54:09

相关推荐

  • 怎么利用JavaScript进行前端安全防护?

    <blockquote&amp;gt;JavaScript在前端安全中起辅助作用,主要用于输入验证、输出编码、DOM净化(如使用DOMPurify防范XSS)、CSP违规报告及客户端存储管理;但所有前端防护均可被绕过,因此服务器端验证才是安全核心。</blockquote&amp…

    好文分享 2025年12月20日
    000
  • 在服务端渲染中,如何解决 JavaScript 代码在 Node.js 和浏览器环境下的差异?

    服务端渲染需实现同构代码,核心是隔离环境差异。1. 避免直接使用 window 等浏览器对象,通过 typeof window 判断执行环境;2. 统一采用 ES Module 语法,由构建工具处理 CommonJS 兼容性,动态导入浏览器专用模块;3. 使用构建插件注入环境变量,区分开发、生产及客…

    2025年12月20日
    000
  • 如何在点击按钮后重新执行脚本

    如何在点击按钮后重新执行脚本 本文将探讨如何在用户点击按钮后重新执行JavaScript脚本,特别是在需要根据用户交互动态更新页面行为或内容时。一个常见的场景是动态改变页面的语言,本文将以切换语言为例,提供详细的步骤和代码示例。 首先,我们需要理解为什么需要重新执行脚本。通常,外部脚本在页面加载时执…

    2025年12月20日
    000
  • 如何在按钮点击后重新执行 JavaScript 脚本

    引言 本文将介绍如何在网页中实现点击按钮后重新执行 JavaScript 脚本的功能,特别是针对需要根据页面语言动态调整行为的脚本。我们将通过监听按钮点击事件,修改 HTML 语言属性,并重新加载或执行脚本的方式,确保脚本能够根据最新的语言设置正确运行,从而提供更好的用户体验。 解决方案 当需要根据…

    2025年12月20日
    000
  • 使用 Eel 和 Python 在 Web 前端异步加载图片

    在构建基于 Eel 的 Web 应用时,经常会遇到需要在 Python 函数执行过程中更新前端界面的需求,例如显示图片。然而,如果 Python 函数执行时间过长,会导致前端界面阻塞,图片无法及时加载,直到 Python 函数执行完毕。为了解决这个问题,我们需要将耗时的 Python 函数异步执行,…

    2025年12月20日
    000
  • 如何构建一个高性能的、基于Canvas的JavaScript数据可视化组件?

    答案:通过按需渲染、减少上下文操作和高效交互检测实现高性能Canvas可视化。使用isDirty标记控制重绘,合并路径绘制,预存静态图层,结合devicePixelRatio适配高清屏,利用空间索引与节流优化交互响应,避免全量刷新,提升性能。 构建一个高性能的基于 Canvas 的 JavaScri…

    2025年12月20日
    000
  • 动态修改语言后重新执行 JavaScript 脚本

    动态修改网页语言后,如果页面上的某些 JavaScript 脚本依赖于当前的语言设置,那么仅仅修改 document.documentElement.lang 属性是不够的。你需要重新执行这些脚本,以使其适应新的语言环境。一种常见的场景是,脚本根据 lang 属性的值来加载不同的资源或显示不同的文本…

    2025年12月20日
    000
  • 前端动画库如何基于JavaScript实现物理运动效果?

    答案:前端动画库通过JavaScript模拟物理规律实现逼真效果,核心是利用弹簧、重力、阻尼等模型结合数值积分计算状态变化,借助requestAnimationFrame同步渲染,主流库如GSAP、framer-motion封装了物理引擎接口,开发者可配置参数实现自然动画,性能优化需关注transf…

    2025年12月20日
    000
  • 使用 async/await 实现异步加载动画:JavaScript 教程

    本文将介绍如何使用 JavaScript 中的 async/await 关键字,结合 Promise 对象,实现一个异步加载动画。通过创建一个 sleep 函数来模拟耗时操作,并在 OSLoad 函数中使用 await 关键字暂停执行,从而实现加载动画的显示,并在加载完成后执行后续代码,避免同步执行…

    2025年12月20日
    000
  • 如何构建一个零依赖的现代化JavaScript库?

    构建零依赖JavaScript库需用ES6+语法开发并转译兼容版本,通过Rollup等打包输出多格式,自行实现对象操作与事件系统,提供TypeScript类型和JSDoc支持,并用npm脚本自动化构建流程。 构建一个零依赖的现代化 JavaScript 库,关键在于保持轻量、可维护和兼容性,同时不引…

    2025年12月20日
    000
  • JavaScript中的Symbol类型有哪些独特的应用场景?

    Symbol是ES6引入的唯一值类型,用于避免属性名冲突、模拟私有属性、定义对象特殊行为(如Symbol.iterator)和替代魔术字符串,提升模块安全与语义清晰性。 Symbol 是 ES6 引入的一种原始数据类型,表示独一无二的值。它的核心特性是唯一性,这使得它在一些特定场景下非常有用。 1.…

    2025年12月20日
    000
  • 使用 async/await 实现 JavaScript 中的异步加载效果

    本文将介绍如何使用 async/await 关键字在 JavaScript 中实现异步加载效果,避免 setTimeout 和 setInterval 带来的回调地狱问题。通过创建一个简单的 sleep 函数,结合 async/await,可以使代码看起来更像同步执行,从而提高代码的可读性和可维护性…

    2025年12月20日
    000
  • JavaScript正则表达式:利用负向先行断言捕获未匹配的剩余内容

    本文深入探讨在JavaScript中使用正则表达式时,如何有效捕获那些未被前置特定分组匹配的字符串片段。通过引入负向先行断言(Negative Lookahead)技术,我们展示了一个通用的模式,该模式能确保正则表达式始终匹配整个字符串,并能将未匹配的部分归入一个单独的捕获组,从而解决传统方法如.*…

    2025年12月20日
    000
  • 如何利用JavaScript进行自动化测试和端到端测试?

    Puppeteer和Cypress结合Jest/Mocha可高效实现JavaScript端到端测试,通过CI/CD集成确保代码质量。 JavaScript 不仅是构建网页交互的核心语言,也广泛用于自动化测试和端到端(E2E)测试。借助现代工具链,开发者可以高效地编写可维护、可重复执行的测试脚本,确保…

    2025年12月20日
    000
  • JavaScript 的动画实现中,requestAnimationFrame 与 CSS 动画孰优孰劣?

    答案:requestAnimationFrame适合复杂交互和动态控制,CSS动画适合简单声明式效果。前者精确控制但代码量大,后者性能优且简洁,应根据场景选择。 在实现网页动画时,requestAnimationFrame 和 CSS 动画各有适用场景,没有绝对的优劣,关键在于使用场景和性能需求。 …

    2025年12月20日
    000
  • 使用 Eel 实现 Python 与前端交互时图片加载延迟的解决方案

    在使用 Eel 框架进行 Python 与%ignore_a_1%交互时,经常会遇到需要在 Python 函数执行过程中更新前端页面的情况,例如动态加载图片。然而,如果 Python 函数执行时间过长,可能会阻塞前端页面的渲染,导致图片无法及时显示,直到 Python 函数执行完毕。这严重影响了用户…

    2025年12月20日
    000
  • 使用 Eel 和 Python 实现前端图片实时更新的教程

    在使用 Eel 框架构建 Web 应用时,有时会遇到这样的问题:Python 后端执行耗时操作时,前端页面会卡住,直到后端操作完成才能响应。这会导致前端图片无法及时更新,影响用户体验。本文将介绍一种解决方案:使用 Celery 异步任务队列,将耗时操作放入后台执行,从而确保前端能够及时响应并更新图片…

    2025年12月20日
    000
  • JavaScript中的代码审查(Code Review)有哪些要点?

    代码审查需关注功能正确性、变量函数设计、编码规范及性能安全。1. 确保逻辑完整,异步处理和错误兜底到位;2. 命名清晰,作用域合理,函数单一职责;3. 遵循ESLint等风格规范,注释适度;4. 避免重复计算、内存泄漏,防范XSS,审慎使用第三方库。 代码审查在JavaScript开发中是保障代码质…

    2025年12月20日
    000
  • JavaScript中的代码混淆和压缩原理是什么?

    代码压缩通过去除空白、注释和简化表达式减小体积,混淆则通过重命名、控制流扁平化和字符串加密增加逆向难度,二者常结合使用以平衡性能与安全。 JavaScript代码混淆和压缩的目的是在不改变程序功能的前提下,减小文件体积并增加代码的阅读难度,主要用于提升加载性能和防止反向工程。虽然两者常被一起使用,但…

    2025年12月20日
    000
  • 解决Eel应用中图片加载延迟的问题

    在使用Eel框架构建Web应用时,经常会遇到这样的情况:Python后端执行耗时操作,导致前端界面更新被阻塞,尤其是在需要动态加载图片时,图片往往需要等待Python函数执行完毕后才能显示,严重影响用户体验。 本文将深入分析这个问题,并提供一种基于Celery的解决方案,实现图片的异步加载,从而有效…

    2025年12月20日
    000

发表回复

登录后才能评论
关注微信