How does Vue 3's Proxy-based reactivity system work internally?
Answer
Vue 3's reactivity is powered by ES2015 Proxy, which intercepts all operations on an object. Core implementation: (1) reactive(obj): wraps obj in a Proxy with handlers for get, set, deleteProperty, has, and ownKeys traps; (2) Track (in get trap): when a property is read, Vue calls track(target, "get", key) — this records that the currently running effect (computed/watch) depends on this property. Dependencies are stored in a WeakMap: target → Map: key → Set<Effect>; (3) Trigger (in set/delete trap): when a property is written, Vue calls trigger(target, "set", key) — this finds all effects that depend on this target.key and re-runs them; (4) ref(val): a ref is an object with a .value getter/setter. The getter calls track(), the setter calls trigger(). For object values, ref wraps them in reactive(). Primitives don't need Proxy — just get/set interception; (5) computed(fn): creates an effect that only re-runs when its dependencies change. Lazy — only evaluates when read. Caches result; re-evaluates when dependencies change; (6) Effect: a function (watcher/computed) that runs within a tracked context. During execution, all reactive reads are recorded as dependencies. Nested effects: Vue maintains an active effect stack — computed within a watch works correctly. Raw access: toRaw(proxy) — access the original object without tracking. markRaw(obj) — prevent object from being made reactive.
Previous
What are advanced Vue Router patterns?
Next
What is Vue's compiler and how does it optimize templates?