Vue2和Vue3响应式的基本实现

目录

  • 简介
  • [Vue2 响应式](#Vue2 响应式)
    • [Vue2 响应式的局限性](#Vue2 响应式的局限性)
  • [Vue3 响应式](#Vue3 响应式)
    • [Vue3 响应式的优点](#Vue3 响应式的优点)
  • [Vue2 和 Vue3 响应式对比](#Vue2 和 Vue3 响应式对比)

简介

在 Vue 框架中,数据的响应式是其核心特性之一。当页面数据发生变化时,我们希望界面能自动更新,而不是手动操作 DOM。这就需要对数据进行监听,并在数据变更时触发 UI 重新渲染。

Vue2 和 Vue3 在实现响应式的方式上有所不同,Vue2 主要依赖 Object.defineProperty,而 Vue3 则引入了 Proxy,大大优化了响应式系统的性能和灵活性。它们都是通过函数来封装响应式对象,方便读取或更新数据时能够进行其他的操作。

Vue2 响应式

Vue2 使用 Object.defineProperty 来拦截对象属性的访问和修改,从而实现响应式。

javascript 复制代码
const obj = {
  a: 1,
  b: 2,
  c: {
    x: 66,
    y: 2,
  }
}

function isObject(v) {
  return typeof v === 'object' && v !== null;
}

function observe(obj) {
  for (const k in obj) {
    let v = obj[k];
    if (isObject(v)) observe(v); // 递归遍历
    Object.defineProperty(obj, k, {
      get() {
        console.log(`读取${k}, 值${v}`);
        return v;
      },
      set(newVal) {
        v = newVal;
        console.log(`更新${k}, 值${v}`);
      }
    });
  }
}

observe(obj);

obj.a;
obj.a = 101;
obj.c.x;
obj.c.x = 166;

Vue2 响应式的局限性

  • 需要遍历对象的每个属性,性能较低。
  • 不能检测到新增或删除的属性。
  • 需要手动调用 Vue.set() 以确保新属性的响应式。

Vue3 响应式

Vue3 使用 Proxy 实现响应式,可以直接监听整个对象,而不是逐个属性。

javascript 复制代码
const obj = {
    a: 1,
    b: 2,
    c: {
        x: 1,
        y: 2,
    }
};

function isObject(v) {
    return typeof v === 'object' && v !== null;
}

function reactive(target) {
    return new Proxy(target, {
        get(target, k) {
            console.log(`读取: ${k}, 值: ${target[k]}`);
            // 读取时才递归生成代理
            if (isObject(target[k])) return reactive(target[k]);
            return target[k];
        },
        set(target, k, newVal) {
            if (newVal === target[k]) return;
            console.log(`更新: ${k}, 值${newVal}`);
            target[k] = newVal;
            return true;
        }
    });
}

const proxy = reactive(obj);

proxy.a;
proxy.a = 100;
proxy.c.x;

Vue3 响应式的优点

  • 直接监听整个对象,无需遍历所有属性。
  • 可以检测到属性的新增和删除。
  • 具有更好的性能和更简洁的代码结构。

Vue2 和 Vue3 响应式对比

对比项 Vue2 (Object.defineProperty) Vue3 (Proxy)
监听方式 逐个属性拦截 整个对象拦截
深度监听 需要递归处理 访问时自动代理
属性新增删除 需要 Vue.set() 处理 可直接监听
数组监听 需要重写数组方法 原生支持
性能 需要遍历所有属性,较低 直接代理整个对象,更高
兼容性 兼容性好,支持 ES5 及以上 需要 ES6 Proxy 支持

Vue3 通过 Proxy 解决了 Vue2 的许多缺陷,使得响应式系统更加高效、灵活和简洁。因此,Vue3 的响应式能力远超 Vue2。


相关推荐
程序员黑豆1 小时前
Java类型推断完全指南:从var到菱形运算符,掌握使用限制与最佳实践
java·前端·ai编程
To_OC2 小时前
踩了个 TS 的坑之后,我终于把 type 和 interface 掰明白了
前端·react.js·typescript
GreenTea2 小时前
深度解读 Anthropic 多智能体报告:更强的模型 ≠ 更好的协调
前端·后端·算法
浮生望2 小时前
前端API工程化:用 Mock 数据与 Axios 配置实现独立于后端的并行开发
前端
2603_965148113 小时前
如何解析JSON数据?API返回的商品信息处理教程
开发语言·数据库·python·自动化·json·api
万少3 小时前
给 DeepSeek Harness 装个"应用商店":一条命令,595 个插件随你逛
前端·javascript·后端
波波0073 小时前
C# 15 重磅新特性: 带标签 break 与 continue:重新定义嵌套循环控制流
服务器·前端·c#
Brown.alexis4 小时前
es6知识点1-自备使用
前端·ecmascript·es6
小爬的老粉丝5 小时前
JavaScript 纯前端预览 WPS:先识别容器,再路由解析器
前端·javascript·wps
知无不研5 小时前
lambda表达式的使用(3)
开发语言·c++·lambda