前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何理解前端的数据响应式?

如何理解前端的数据响应式?

作者头像
友儿
发布2024-08-27 11:08:23
870
发布2024-08-27 11:08:23
举报
文章被收录于专栏:友儿

数据响应式是一种编程概念,在许多现代编程语言和框架中都有广泛应用,尤其是在前端开发领域。其本质确实如你所说,当数据发生变化时,自动运行一些相应的函数。

实现原理

  • 观察者模式
    • 数据响应式通常基于观察者模式实现。数据被视为被观察的对象,而那些在数据变化时需要执行的函数则是观察者。当数据发生变化时,通知所有注册的观察者执行相应的操作。
    • 例如,在 Vue.js 中,通过使用 ES6 的 Proxy 对象或 Object.defineProperty 方法来拦截对数据的访问和修改,当数据被修改时,触发依赖收集过程,通知相关的组件重新渲染。
  • 依赖收集与触发
    • 在数据响应式系统中,当一个函数依赖于某个特定的数据时,系统会记录这种依赖关系。当数据发生变化时,系统能够准确地找到依赖于该数据的函数,并触发它们执行。
    • 以 Vue.js 为例,当一个组件的模板中使用了某个数据,在组件渲染过程中,会建立对该数据的依赖。当数据变化时,Vue.js 能够快速确定哪些组件需要重新渲染,并执行相应的渲染函数。

手写一个简单的数据响应式程序

代码语言:javascript
复制
/**
 * 观察一个对象,并为其属性创建 getter 和 setter
 * 当属性被读取时,会进行依赖收集
 * 当属性被修改时,会触发所有收集到的依赖函数
 *
 * @param {Object} obj - 要观察的对象
 */
function observe(obj) {
    for (const key in obj) {
        let internalValue = obj[key];
        let funcs = new Set();
        Object.defineProperty(obj, key, {
            get: function () {
                // 依赖收集
                if (window.__func) {
                    funcs.add(window.__func);
                }
                return internalValue;
            },
            set: function (value) {
                internalValue = value;
                // 派发更新
                for (const func of funcs) {
                    func();
                }
                funcs.clear();
            }
        });

    }
}
/**
 * 自动执行一个函数,并在执行完毕后清理
 *
 * @param {Function} func - 要自动执行的函数
 *
 * @example
 * autoFun(test);
 */
function autoFunc(func) {
    window.__func = func;
    func();
    window.__func = null;
}
代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>手写简单的数据响应式</title>
</head>

<body>
    <div class="username">{{user.name}}</div>
    <script src="index.js"></script>
    <script>

        // 创建一个名为 user 的对象,包含 name 和 age 属性
        var user = {
            name: "John",
            age: 30
        }

        // 调用 observe 函数,对 user 对象进行监听
        observe(user);

        // 定义一个名为 test 的函数,用于更新页面上显示的用户名
        function test() {
            document.querySelector(".username").innerHTML = user.name;
        }

        // 调用 autoFunc 函数,自动执行 test 函数,并将 test 函数作为依赖添加到 observe 函数中
        autoFunc(test);

        // 更新 user 对象的 name 属性值
        user.name = "Jane";

    </script>
</body>

</html>

代码分析

  • observe 函数: 这个函数用于观察一个对象的所有属性。对于对象中的每个属性,它使用 Object.defineProperty 来定义一个 getter 和 setter。getter 用于收集依赖(即当前正在访问该属性的函数),setter 用于在属性值变化时更新依赖。它使用了一个 for...in 循环来遍历对象的每个属性。
  • autoFunc 函数: 这个函数用于自动执行一个函数,并在执行完毕后清理。它通过将函数赋值给一个临时属性 window.__func,模拟了一个全局变量,使得 observe 函数中的 getter 能够收集到当前正在访问的函数。在执行完函数后,它将 window.__func 设置回 null,以便进行下一次的依赖收集。
  • 使用示例: 代码的后半部分是 observe 和 autoFunc 函数的使用示例。它创建了一个 user 对象,然后使用 observe(user) 来观察它。接着,它定义了一个 test 函数,用于更新文档中某个元素的内容。通过调用 autoFunc(test),test 函数被执行,并且由于 window.__func 的设置,它被添加到 user.name 的依赖集合中。随后,当 user.name 的值被更改为 "Jane" 时,test 函数会因为 observe 函数中定义的 setter 逻辑而自动再次执行。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
腾讯云代码分析
腾讯云代码分析(内部代号CodeDog)是集众多代码分析工具的云原生、分布式、高性能的代码综合分析跟踪管理平台,其主要功能是持续跟踪分析代码,观测项目代码质量,支撑团队传承代码文化。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档