Suggest an editImprove this articleRefine the answer for “Proxy and the new reactivity system”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**Proxy** is the mechanism the new Vue 3 reactivity system is built on: it intercepts `get`, `set`, and `delete` operations, so Vue automatically tracks new properties, array elements, nested objects, and `Map`/`Set` collections without manual `Vue.set()`. **Key point:** this solves the main limitations of Vue 2's reactivity and makes it universal, scalable, fast, and precise.Shown above the full answer for quick recall.Answer (EN)Image## 1. Problem: inability to track new properties ### In Vue 2 Reactivity was created using `Object.defineProperty()`. It "wrapped" **only the fields that existed** at initialization time. ```javascript data() { return { user: { name: 'Tim' } } } this.user.age = 30 // not reactive! Vue.set(this.user, 'age', 30) // needs to be done manually ``` ### In Vue 3 `Proxy` intercepts all `get`, `set`, `delete` operations, so Vue automatically tracks new fields: ```javascript const user = reactive({ name: 'Tim' }) user.age = 30 // reactive! delete user.name // also reactive! ``` **Problem solved**: properties can be added/removed dynamically, without `Vue.set()`. --- ## 2. Problem: poor handling of arrays ### In Vue 2 Arrays were not fully reactive: - Changes by index were not tracked: ```javascript this.items[2] = 'new' // will not work ``` - `Vue.set(this.items, 2, 'new')` had to be used instead. - Vue "patched" (`override`) array methods (`push`, `pop`, `splice`), which was cumbersome and reduced performance. ### In Vue 3 `Proxy` intercepts all array operations, including indices and length. ```javascript const arr = reactive(['a', 'b']) arr[1] = 'x' // reactive arr.push('c') // reactive arr.length = 0 // reactive ``` **Problem solved**: arrays now work fully natively. --- ## 3. Problem: nested objects ### In Vue 2 During initialization, Vue recursively walked through all the fields of an object to "wrap" them in getters/setters. This was: - Slow with large data. - Impossible for objects added later. ```javascript this.obj = { nested: { value: 1 } } // obj.nested is not reactive until it goes through defineReactive() ``` ### In Vue 3 `Proxy` creates reactivity **lazily** (on demand): on the first access to a nested object, it is automatically wrapped in a `Proxy`. ```javascript const state = reactive({ nested: { count: 0 } }) state.nested.count++ // reactive, even though the object is nested ``` **Problem solved**: instant reactivity at any nesting level. --- ## 4. Problem: inability to track collections (`Map`, `Set`, `WeakMap`) ### In Vue 2 These data structures could not be reactive at all, since `Object.defineProperty()` cannot intercept their methods (`set`, `get`, `add`, `delete`). ### In Vue 3 `Proxy` intercepts collection methods through special traps. Reactive `Map` and `Set` can now be used freely: ```javascript const map = reactive(new Map()) map.set('key', 'value') // reactive map.delete('key') // reactive ``` **Problem solved**: modern data structures can be used with full reactivity. --- ## 5. Problem: redundant updates and performance leaks ### In Vue 2 The `Dep` dependency system worked at the property level, and sometimes subscribers fired an extra time even if the value had not changed. ```javascript this.value = 10 this.value = 10 // still triggers an update! ``` ### In Vue 3 The new `track()` / `trigger()` system became **granular and precise**: - Vue compares the old and new value. - It tracks dependencies by a specific key. - It minimizes repeated updates. **Problem solved**: fewer unnecessary re-renders, higher performance. --- ## 6. Problem: inability to use reactivity outside a component ### In Vue 2 Reactivity was tightly coupled to the component lifecycle. You could not create "reactive state" outside a component without an internal API. ### In Vue 3 Reactivity was moved into a separate `@vue/reactivity` package, and is available via `ref()`, `reactive()`, `computed()`, `watchEffect()`. ```javascript // can be used even without a Vue component import { reactive, watchEffect } from 'vue' const state = reactive({ count: 0 }) watchEffect(() => { console.log(state.count) }) state.count++ // reactive even in Node.js ``` **Problem solved**: reactivity became universal, independent of components. --- ## 7. Problem: initialization performance ### In Vue 2 To make an object reactive, Vue walked through **all of its properties** and called `Object.defineProperty()` on each one. If `data` was large, the component mounted slowly. ### In Vue 3 `Proxy` does not require walking through properties, Vue creates a single proxy object and handles access "on demand". **Problem solved**: component initialization became many times faster. --- ## 8. Problem: opacity of debugging and predictability ### In Vue 2 In some cases reactivity worked "magically": it was impossible to tell exactly where something was triggered, especially with `Vue.set()`. ### In Vue 3 The new system is transparent: - There are separate low-level APIs (`effect`, `track`, `trigger`). - Dependencies can easily be logged and debugged. - DevTools shows a detailed map of reactive connections. **Problem solved**: better understanding and control over reactivity. --- ## Summary: which problems Proxy solves | Problem | Vue 2 | Vue 3 (Proxy) | |---|---|---| | Adding/removing properties | No | Yes | | Working with arrays | Partial | Full | | Nested objects | Not automatic | Automatic | | Map/Set support | No | Yes | | Creation performance | Low | High | | Tracking granularity | Coarse | Precise | | Use outside components | No | Yes | | Debugging transparency | Limited | Excellent | --- ## In short > The new Vue 3 reactivity system built on `Proxy` solved the main problems of the old version, > making reactivity **universal, scalable, fast, and precise**, > while keeping Vue's declarative style simple.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.