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。


相关推荐
人工智能训练2 小时前
【极速部署】Ubuntu24.04+CUDA13.0 玩转 VLLM 0.15.0:预编译 Wheel 包 GPU 版安装全攻略
运维·前端·人工智能·python·ai编程·cuda·vllm
会跑的葫芦怪2 小时前
若依Vue 项目多子路径配置
前端·javascript·vue.js
兩尛2 小时前
c++知识点2
开发语言·c++
fengfuyao9852 小时前
海浪PM谱及波形的Matlab仿真实现
开发语言·matlab
xiaoye-duck3 小时前
C++ string 底层原理深度解析 + 模拟实现(下)——面试 / 开发都适用
开发语言·c++·stl
xiaoqi9223 小时前
React Native鸿蒙跨平台如何进行狗狗领养中心,实现基于唯一标识的事件透传方式是移动端列表开发的通用规范
javascript·react native·react.js·ecmascript·harmonyos
jin1233224 小时前
React Native鸿蒙跨平台剧本杀组队消息与快捷入口组件,包含消息列表展示、快捷入口管理、快捷操作触发和消息详情预览四大核心功能
javascript·react native·react.js·ecmascript·harmonyos
Hx_Ma164 小时前
SpringMVC框架提供的转发和重定向
java·开发语言·servlet
期待のcode4 小时前
原子操作类LongAdder
java·开发语言
烬头88215 小时前
React Native鸿蒙跨平台实现二维码联系人APP(QRCodeContactApp)
javascript·react native·react.js·ecmascript·harmonyos