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。


相关推荐
云边小网安43 分钟前
java集合(十) ---- LinkedList 类
java·开发语言·青少年编程·java集合
10年前端老司机44 分钟前
什么!纯前端也能识别图片中的文案、还支持100多个国家的语言
前端·javascript·vue.js
摸鱼仙人~1 小时前
React 性能优化实战指南:从理论到实践的完整攻略
前端·react.js·性能优化
程序员阿超的博客2 小时前
React动态渲染:如何用map循环渲染一个列表(List)
前端·react.js·前端框架
magic 2452 小时前
模拟 AJAX 提交 form 表单及请求头设置详解
前端·javascript·ajax
Zephyrtoria2 小时前
区间合并:区间合并问题
java·开发语言·数据结构·算法
你怎么知道我是队长3 小时前
GO语言---匿名函数
开发语言·后端·golang
lansye3 小时前
侃侃AI编程
开发语言·qt·ai编程
uyeonashi4 小时前
【QT】窗口详解
开发语言·c++·qt·学习
Hello eveybody5 小时前
C++介绍整数二分与实数二分
开发语言·数据结构·c++·算法