Vue2 、Vue3 响应式对比及优劣

Vue2 的响应式:Object.defineProperty

Vue2是遍历对象的每一个属性,给单个属性单独设置getter/setter来监听。


Vue3对比Vue2的优势(通俗+面试要点)

  1. ✅ 能监听新增、删除属性

Vue2:初始化的时候遍历属性。后续新加的属性、删掉属性,监听不到 ,需要用$set。

Vue3:Proxy代理整个对象 ,不是单个属性,新增/删除属性都能拦截,不用$set。

  1. ✅ 原生数组可以完整监听

Vue2重写了数组7个方法,但是通过索引修改数组、修改数组length,监听不到。

Vue3 Proxy直接代理数组,数组下标赋值、修改length都能捕获。

  1. ✅ 可以监听 Map、Set 这类集合类型

Vue2只能监听普通对象、数组;

Vue3 Proxy天然支持 Map / Set / WeakMap / WeakSet。

  1. ✅ 懒代理(性能更好)

Vue2初始化,递归遍历全部嵌套对象,一次性把所有属性加上get/set,对象很大的时候初始化慢。

Vue3:外层对象先代理,嵌套对象不会立刻处理,访问到内层属性的时候才去代理。节省初始化开销,大数据场景更快。

  1. ✅ 代码层面:

Object.defineProperty只能监听属性读写;Proxy能拦截更多操作(in判断、delete等)

短板顺带提(面试常问)

Proxy不支持IE浏览器,Vue3直接放弃IE;Vue2可以兼容IE。

🎤面试口述精简版(直接背)

Vue3响应式核心是Proxy + Reflect。Proxy代理整个目标对象,拦截读写、新增、删除等操作,配合track收集依赖、trigger触发更新。

Vue2使用Object.defineProperty,只能预先遍历属性监听。相比Vue2:

  1. 可以监听新增、删除属性,不再需要$set;

  2. 支持数组下标、length修改监听;

  3. 支持Map、Set等集合;

  4. 懒代理,初始化性能更好;

  5. 缺点是Proxy无法兼容IE浏览器。

  1. 要不要我出一道Vue2/Vue3响应式的面试问答题,你来口述回答?

Proxy 详解(面试核心)

基础信息

读音:英 /ˈprɒksi/ ,美 /ˈprɑːksi/ ,中文近似谐音:普若克西

单词本意:代理。ES6 的 Proxy 就是代理对象,用来拦截目标对象的操作。

复制代码

const p = new Proxy(target, handler) // target:要代理的目标对象 // handler:拦截器,自定义捕获函数(get/set 等)

易混区分与注意点

  • Reflect(/rɪˈflekt/,反射):常和 Proxy 搭配使用

  • Proxy 不能直接监听普通原始基本类型,只能代理对象、数组这类引用类型

一句话面试简述

Proxy 用于创建一个对象的代理,从而实现基本操作的拦截和自定义(属性读取、赋值、删除等),可以监听对象,是 Vue3 响应式的核心原理。

Vue2 vs Vue3 响应式对比

面试最爱问:为什么 Vue3 要用 Proxy 重写响应式?对比表直接背:

对比维度 Vue2:Object.defineProperty Vue3:Proxy
核心机制 劫持对象已有属性的 getter / setter 代理整个对象,拦截对对象的操作
新增 / 删除属性 ❌ 监听不到,需 Vue.set / Vue.delete 补救 ✅ 天然支持(has / deleteProperty 拦截)
数组监听 ⚠️ 下标赋值、length 变化监听不到;重写 push/pop 等 7 个方法部分实现 ✅ 天然支持索引赋值、length 变化
嵌套对象 初始化时递归遍历、一次性深度劫持(开销大) ✅ 懒代理:访问到嵌套对象时才递归代理
拦截能力 仅 get / set(数组靠方法重写) 13 种捕获器:get / set / has / deleteProperty / ownKeys / apply / construct 等
支持的容器 普通对象、数组 额外支持 Map、Set、WeakMap、WeakSet
性能 初始化递归开销大,深层对象卡顿 懒代理 + 按需触发,整体更优
兼容性 IE9+(IE8 不支持) IE 全系不支持(Vue3 放弃 IE11)
语言层面 JS 的补丁式方案 ES6 原生特性

Proxy 面试常见问题(逐题)

Q1:Proxy 和 Object.defineProperty 有什么区别?

核心区别:defineProperty 劫持的是单个已存在属性的读写 ,需要遍历对象逐个定义,新增/删除属性天然管不到;Proxy 代理的是整个对象,任何对对象的操作(读取、赋值、删除、遍历、函数调用等)都会被拦截,覆盖面更全。

Q2:为什么 Vue3 用 Proxy 替代 Object.defineProperty?

解决 Vue2 的三大痛点:① 新增 / 删除属性监听不到;② 数组下标赋值和 length 变化监听不到;③ 初始化要递归遍历所有属性,深层对象性能开销大。Proxy 配合懒代理,这三点全部解决,还顺带支持 Map / Set。

Q3:为什么 Proxy 不能直接监听基本类型?

因为基本类型(string / number / boolean 等)没有可拦截的属性操作,new Proxy(1, {}) 会直接报错(target 必须是非基本类型对象)。所以 Vue3 用 ref 把基本类型包装成 { value } 对象后再代理。

Q4:Proxy 有哪些捕获器(trap)?

共 13 种:get、set、has、deleteProperty、ownKeys、getOwnPropertyDescriptor、defineProperty、getPrototypeOf、setPrototypeOf、isExtensible、preventExtensions、apply、construct。Vue3 核心只用 get(收集依赖)和 set(触发更新),再配合 has / deleteProperty / ownKeys 处理新增、删除、遍历。

Q5:Reflect 有什么作用?为什么和 Proxy 搭配使用?

Reflect 提供与 Proxy 捕获器一一对应 的默认方法(Reflect.get / Reflect.set / Reflect.has...)。搭配原因:① this 指向正确------Reflect.get(target, key, receiver) 可显式指定 receiver,避免 getter 里 this 指向错误;② set 返回布尔值,能判断赋值是否成功;③ 与捕获器同名同参,语义统一、代码简洁。

Q6:Vue3 的 reactive 是怎么实现的?

核心就是 new Proxy(target, handler):在 get 中调用 track 收集依赖(effect),在 set 中调用 trigger 触发更新。嵌套对象采用懒代理:get 时发现属性值还是对象,才递归 reactive,访问到才代理,性能更好。

Q7:Proxy 有什么局限性?

① 只能代理引用类型,基本类型要靠 ref 包装;② 兼容性:IE 全系不支持,Vue3 因此放弃 IE11;③ 相比直接属性访问有性能损耗;④ 代理后对象身份变化(=== 判断失效),个别依赖身份判断的库可能受影响。

Q8:Vue2 为什么监听不到数组下标变化?

defineProperty 只能劫持已存在的属性,数组下标赋值(arr0 = x)和 length 变化不会触发 setter。Vue2 靠重写 push / pop / shift / unshift / splice / sort / reverse 这 7 个方法实现部分监听,但 arr0 = x 这类操作依然监听不到,只能靠 Vue.set 补救。

相关推荐
NetX行者19 小时前
用 Vite + Vue3 + UnoCSS 搭建企业级项目模板(一):基础骨架
vue·vite·unocss
java水泥工1 天前
什么是前端
java·vue·html5
mont evergreen2 天前
一封从外部世界寄来的信:二维码数据如何穿越三重门,抵达你的屏幕
electron·vue·事件
志尊宝3 天前
Vue3 零基础每日笔记(071):暗黑模式与主题切换——CSS 变量 + Element Plus 暗黑方案
前端·css·笔记·vue·html·前端开发·软件开发
怦然丶心动3 天前
用 Java 把干支历法算清楚:从节气切年到可读摘要
java·算法·vue·独立开发·spring boot / spring
我最爱吃鱼香茄子5 天前
【毕业设计优选】人力资源管理系统|Java|SpringBoot|Vue|前后端分离|带详细文档+部署教学视频
java·vue·毕业设计·springboot
骑着蜗牛撵大象3276 天前
SpringBoot+Vue3 企业智能体侧挂架构:独立服务、独立数据库与主线零侵入落地
数据库·spring boot·架构·vue·springboot·事件驱动·服务拆分
码艺-Alimjan8 天前
Tauri 网站To桌面应用实战总结
前端·javascript·vue
liangshiwei11 天前
ABP x Vue:介绍 ABP Vue UI
vue·abp