Under The Hood
frontend vue Vue 3.x (Proxy-based)

Vue 3 reactivity: Proxy vs Vue 2 getter/setter

Last updated
Prerequisites:
Vue component basics
JavaScript Proxy and Object.defineProperty
  • vue
  • reactivity
  • proxy
  • defineproperty
  • vue3
  • javascript

Read at your depth

The practical view

Vue 2 wrapped object properties with Object.defineProperty, converting each existing key into a reactive getter/setter. That is why adding a new property to a reactive object required this.$set(obj, 'key', value) — the new key had no getter/setter, so it was invisible to reactivity. Vue 3 uses JavaScript Proxy: reactive(obj) returns a proxy that intercepts get, set, has, deleteProperty, and more, so brand-new keys are reactive automatically, no $set needed. In practice this means arrays indexed by number, added properties, and destructuring behavior all changed: obj['newKey'] = x just works, and arr[3] = v is tracked.

The same idea in other frameworks

react equivalent
const [obj, setObj] = useState({ count: 0 });
// updates are immutable: setObj({ ...obj, count: obj.count + 1 })

Legacy vs modern

Adding a key to a reactive object: $set vs direct assignment

Vue 2 required $set for new keys because defineProperty ran once at init; the Proxy in Vue 3 makes direct assignment reactive for any key, existing or new.

before → after
Vue 2 defineProperty
this.$set(this.user, 'role', 'admin');
// plain assignment would not trigger updates:
Vue 3 Proxy
state.user.role = 'admin'; // tracked by the set trap

Interview gotchas

Under The Hood — a multi-depth technical interview hub.

Press ⌘ K to search.