当前位置: 首页 > news >正文

vue3响应式数据原理

Vue 3 的响应式系统与 Vue 2 有显著不同,Vue 3 使用了 Proxy 替代了 Vue 2 中的 Object.defineProperty,这使得 Vue 3 的响应式系统更加灵活和强大


Vue 3 响应式原理的核心

  1. Proxy

    • Vue 3 使用 Proxy 来拦截对象的操作(如读取、赋值、删除等)。
    • Proxy 可以监听整个对象,而不需要像 Object.defineProperty 那样递归遍历每个属性。
  2. Reflect

    • Reflect 是一个内置对象,提供了与 Proxy 拦截操作对应的方法。
    • Vue 3 使用 Reflect 来执行默认行为(如读取属性值、设置属性值等)。
  3. 依赖收集与派发更新

    • Vue 3 仍然使用依赖收集和派发更新的机制,但实现方式更加简洁。
    • 通过 effect 函数(类似于 Vue 2 的 watchEffect)来追踪依赖。

简单实现 Vue 3 响应式系统

以下是一个简化版的 Vue 3 响应式系统实现:

// 存储当前正在执行的 effect 函数
let activeEffect = null;

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

// 创建响应式对象
function reactive(obj) {
    return new Proxy(obj, {
        get(target, key, receiver) {
            const dep = getDep(target, key);
            dep.depend(); // 依赖收集
            return Reflect.get(target, key, receiver);
        },
        set(target, key, value, receiver) {
            const dep = getDep(target, key);
            const result = Reflect.set(target, key, value, receiver);
            dep.notify(); // 派发更新
            return result;
        }
    });
}

// 存储每个对象的每个 key 对应的 Dep 实例
const targetMap = new WeakMap();

function getDep(target, key) {
    let depsMap = targetMap.get(target);
    if (!depsMap) {
        depsMap = new Map();
        targetMap.set(target, depsMap);
    }
    let dep = depsMap.get(key);
    if (!dep) {
        dep = new Dep();
        depsMap.set(key, dep);
    }
    return dep;
}

// effect 函数,用于追踪依赖
function effect(fn) {
    activeEffect = fn;
    fn(); // 执行函数,触发 getter,收集依赖
    activeEffect = null;
}

// 测试
const state = reactive({ count: 0, list: [1, 2, 3] });

effect(() => {
    console.log('Count:', state.count);
});

effect(() => {
    console.log('List:', state.list);
});

state.count++; // 输出: Count: 1
state.list.push(4); // 输出: List: [1, 2, 3, 4]

代码解析

  1. reactive 函数

    • 使用 Proxy 包装对象,拦截 getset 操作。
    • get 中调用 dep.depend() 收集依赖。
    • set 中调用 dep.notify() 派发更新。
  2. Dep

    • 用于存储依赖(effect 函数)。
    • 提供 depend 方法收集依赖,notify 方法派发更新。
  3. effect 函数

    • 类似于 Vue 2 的 watchEffect,用于执行副作用函数并追踪依赖。
    • 在执行过程中,activeEffect 会被设置为当前函数,从而在 get 中被收集。
  4. targetMapgetDep

    • targetMap 是一个 WeakMap,用于存储每个对象及其对应的 depsMap
    • depsMap 是一个 Map,用于存储每个 key 对应的 Dep 实例。
    • getDep 函数用于获取或创建 Dep 实例。

Vue 3 的优势

  1. 更好的性能

    • Proxy 可以监听整个对象,而不需要递归遍历每个属性。
    • 只有在访问属性时才会创建 Dep,减少了初始化开销。
  2. 更强大的功能

    • Proxy 可以拦截更多操作,如 deletePropertyhas 等。
    • 支持数组的 pushpop 等操作,无需额外处理。
  3. 更简洁的代码

    • 依赖收集和派发更新的逻辑更加清晰和集中。

总结

Vue 3 的响应式系统基于 ProxyReflect,相比 Vue 2 的 Object.defineProperty,具有更好的性能和更强大的功能。通过 effect 函数追踪依赖,Dep 类管理依赖,Proxy 拦截操作,Vue 3 实现了一个高效且灵活的响应式系统。简化版的 Vue 3 的核心原理。

相关文章:

  • 面向机器人操作的协同、泛化和高效的双-系统
  • GoFly框架中集成Bolt 和badfer两个Go语言嵌入式键值数据库
  • uniapp在app下使用mqtt协议!!!支持vue3
  • DeepSeek技术:数字化时代的商业规则重塑者
  • 19、《Springboot+MongoDB整合:玩转文档型数据库》
  • llama.cpp 一键运行本地大模型 - Windows
  • esp工程报错:something went wrong when trying to build the project esp-idf 一种解决办法
  • [AI相关]问问DeepSeek如何基于Python,moviePy实现视频字幕功能
  • 【量化策略】动量反转策略
  • Docker:Docker从入门到精通(一)- Docker简介
  • 如何实现修改jvm中类的属性开源项目
  • react使用react-quill 富文本插件、加入handlers富文本不显示解决办法
  • vLLM专题(十一)-工具调用(Tool Calling)
  • 详解传输层协议TCP/UDP
  • 力扣hot100——岛屿数量 岛屿问题经典dfs总结
  • 安全面试5
  • 常见高低压开关柜
  • 「软件设计模式」责任链模式(Chain of Responsibility)
  • Python Seaborn库使用指南:从入门到精通
  • RPA自动化测试流程构建体系搭建 实例
  • 天算星座二期首批卫星成功发射,将助力6G空天信息基础设施建设
  • 上海博物馆展览进校园,“小先生”传递文物知识
  • 著名心血管病学专家李国庆教授逝世,享年63岁
  • 马上评|重病老人取款身亡,如何避免类似悲剧?
  • 时隔三年,俄乌直接谈判重启
  • 哪种“网红减肥法”比较靠谱?医学专家和运动专家共同解答