Vue2 源码探究响应式原理

简介: 【8月更文挑战第28天】Vue2 源码探究响应式原理

Vue.js 的响应式系统是它的核心特性之一,它允许开发者以声明式的方式将数据渲染到 DOM 上,并在数据变化时自动更新视图。Vue 2 中的响应式系统主要通过 Object.defineProperty 方法来实现,这一方法允许在对象上定义或修改属性的 getter/setter。接下来,我将通过代码示例和解释来阐述 Vue 2 中的响应式原理。

1. 响应式数据的基础:Object.defineProperty

Vue 2 使用 Object.defineProperty 来劫持对象属性的 getter 和 setter,以便在访问或修改这些属性时执行特定的逻辑(如依赖收集、派发更新等)。

function defineReactive(obj, key, val) {
   
    // 递归处理子对象
    observe(val);

    // 创建一个依赖收集器
    const dep = new Dep();

    // 使用 Object.defineProperty 定义响应式属性
    Object.defineProperty(obj, key, {
   
        enumerable: true,
        configurable: true,
        get: function reactiveGetter() {
   
            // 依赖收集
            const target = Dep.target;
            if (target) {
   
                dep.depend();
                if (isArray(val)) {
   
                    dependArray(val);
                }
            }
            return val;
        },
        set: function reactiveSetter(newVal) {
   
            // 新的值与旧值相同时不处理
            if (newVal === val) return;
            // 递归设置子对象的响应性
            observe(newVal);
            // 派发更新
            dep.notify();
            val = newVal;
        }
    });
}

// 依赖收集器
class Dep {
   
    constructor() {
   
        this.subscribers = new Set();
    }
    depend() {
   
        if (Dep.target) {
   
            this.subscribers.add(Dep.target);
        }
    }
    notify() {
   
        this.subscribers.forEach(sub => sub.update());
    }
}

// 全局变量,用于依赖收集
Dep.target = null;

// 观察一个对象
function observe(value) {
   
    if (!isObject(value) || value instanceof VNode) {
   
        return;
    }
    Object.keys(value).forEach(key => {
   
        defineReactive(value, key, value[key]);
    });
}

// 辅助函数
function isObject(value) {
   
    return value !== null && typeof value === 'object';
}

2. 组件的响应式更新

在 Vue 组件中,data 里的属性会被转换成响应式数据。当这些属性在模板中被访问时,Vue 会使用 Dep.target 来标记当前正在计算的 watcher(通常是渲染 watcher)。

// 假设的组件初始化
function initComponent(component) {
   
    const data = component.data();
    observe(data);
    // 假设的渲染函数
    function render() {
   
        Dep.target = new Watcher(component, function updateComponent() {
   
            // 渲染逻辑
        });
        // 访问响应式数据,触发 getter
        console.log(data.message);
        Dep.target = null;
    }
    render();
}

// 简单的 Watcher 类
class Watcher {
   
    constructor(vm, cb) {
   
        this.cb = cb;
        this.vm = vm;
        this.deps = [];
        this.get(); // 触发 getter,进行依赖收集
    }
    get() {
   
        Dep.target = this;
        // 假设的访问响应式数据
        // this.vm.data.message;
        Dep.target = null;
    }
    update() {
   
        this.cb();
    }
}

总结

上述代码展示了 Vue 2 中响应式系统的基础实现。通过 Object.defineProperty,Vue 能够拦截对对象属性的访问和修改,从而执行依赖收集和派发更新等操作。在组件的渲染过程中,Vue 会利用 Dep.target 来标记当前正在计算的 watcher,并在访问响应式属性时通过 getter 进行依赖收集。当响应式数据变化时,setter 会被触发,进而通知所有依赖该数据的 watcher 执行更新操作,实现视图的自动更新。

虽然这个示例较为简化,但它捕捉了 Vue 2 响应式系统的核心思想和关键步骤。在实际应用中,Vue 还会处理更复杂的场景,如数组变化检测、计算属性、侦听器等。

目录
相关文章
|
前端开发 JavaScript 程序员
真正解决办法:FTP 执行命令时500 Illegal PORT command
真正解决办法:FTP 执行命令时500 Illegal PORT command
3273 0
|
4月前
|
存储 缓存 固态存储
SSD固态硬盘使用指南:提升速度与延长寿命的技巧
固态硬盘(SSD)以其高速读写和流畅体验受到用户青睐,但合理使用与维护才能充分发挥其性能并延长寿命。本文详解SSD工作原理、优化技巧及注意事项:开启TRIM功能、避免碎片整理、保持闲置空间、管理虚拟内存、关闭不必要服务、启用AHCI模式等。同时建议减少频繁写入、定期检测健康状态、更新固件,并通过数据备份和散热管理进一步延长SSD寿命。掌握这些方法,让SSD始终高效稳定运行。
SSD固态硬盘使用指南:提升速度与延长寿命的技巧
|
11月前
|
存储 Web App开发 安全
如何防范 CSRF 攻击
CSRF(跨站请求伪造)攻击是一种常见的安全威胁。防范措施包括:使用Anti-CSRF Token、检查HTTP Referer、限制Cookie作用域、采用双重提交Cookie机制等,确保请求的合法性与安全性。
|
关系型数据库 MySQL 数据库
mysql下的max_allowed_packet参数设置
mysql下的max_allowed_packet参数设置
1521 0
|
存储 缓存 NoSQL
深入解析Memcached:内部机制、存储结构及在大数据中的应用
深入解析Memcached:内部机制、存储结构及在大数据中的应用
|
监控 数据可视化 前端开发
基于python django生产数据与计划大屏,可链接数据库
本文介绍了一个基于Python Django框架开发的生产数据与计划大屏系统,该系统能够实时采集和展示生产数据,支持数据可视化和实时更新,以提高生产监控的效率和质量。
230 3
|
Java 关系型数据库 微服务
Seata常见问题之项目一直启动不成功如何解决
Seata 是一个开源的分布式事务解决方案,旨在提供高效且简单的事务协调机制,以解决微服务架构下跨服务调用(分布式场景)的一致性问题。以下是Seata常见问题的一个合集
1117 0
|
JavaScript 前端开发
js继承的超详细讲解:原型链继承、构造函数继承、组合继承、原型式继承、寄生式继承、寄生组合式继承、class继承
js继承的超详细讲解:原型链继承、构造函数继承、组合继承、原型式继承、寄生式继承、寄生组合式继承、class继承
709 0
|
机器学习/深度学习 存储 弹性计算
阿里云服务器ECS架构ARM计算介绍
阿里云服务器ECS架构ARM计算介绍,ARM计算架构特性:ARM计算架构采用阿里云自研倚天710 ARM架构CPU,依托第四代神龙架构,提供稳定可预期的超高性能。同时通过芯片快速路径加速手段,完成存储、网络性能以及计算稳定性的数量级提升。基于ARM架构的实例规格,每一个vCPU都对应一个处理器的物理核心,具有性能稳定且资源独享的特点
555 0