Vue but underthehood: Part 1 - The Proxy Foundation
Introduction
Welcome to the first part of "Vue but underthehood" - a deep dive into Vue 3's internal mechanisms. In this series, we'll explore how Vue 3 implements its powerful reactivity system using modern JavaScript features.
In this first installment, we'll examine The Proxy Foundation - the cornerstone of Vue 3's reactivity system.
What are JavaScript Proxies?
JavaScript Proxies allow you to create a wrapper around an object that can intercept and redefine fundamental operations. This is exactly what Vue 3 uses to track dependencies and trigger updates.
const target = { count: 0 };
const handler = {
get(target, property, receiver) {
console.log(`Getting ${property}`);
return Reflect.get(target, property, receiver);
},
set(target, property, value, receiver) {
console.log(`Setting ${property} to ${value}`);
return Reflect.set(target, property, value, receiver);
},
};
const proxy = new Proxy(target, handler);
How Vue Uses Proxies
Vue 3's reactive() function creates a Proxy around your data objects. When you access or modify properties, Vue can:
- Track which components are reading which properties (dependency collection)
- Trigger updates when those properties change (effect execution)
import { reactive, effect } from "vue";
const state = reactive({ count: 0 });
effect(() => {
console.log(`Count is: ${state.count}`);
});
// This will trigger the effect
state.count++;
The ReactiveHandler
At the heart of Vue's reactivity is the ReactiveHandler - a set of trap functions that intercept operations:
class ReactiveHandler implements ProxyHandler<Target> {
get(target: Target, key: string | symbol, receiver: object) {
// Track dependency
track(target, TrackOpTypes.GET, key);
const res = Reflect.get(target, key, receiver);
return res;
}
set(target: Target, key: string | symbol, value: unknown, receiver: object) {
const oldValue = target[key];
const result = Reflect.set(target, key, value, receiver);
// Trigger effects if value changed
if (oldValue !== value) {
trigger(target, TriggerOpTypes.SET, key, value, oldValue);
}
return result;
}
}
Key Takeaways
- Vue 3 uses JavaScript Proxies as the foundation of its reactivity system
- Proxies allow Vue to intercept property access and modification
- The
gettrap enables dependency tracking - The
settrap enables effect triggering - This approach is more powerful and performant than Vue 2's
Object.defineProperty
What's Next?
In Part 2: The Language Engine, we'll explore how TypeScript enhances Vue's development experience and how Vue's type system works internally.
This is Part 1 of the "Vue but underthehood" series. Stay tuned for more deep dives into Vue's internal mechanisms!
- ← Previous
JS Playground Demo - Next →
Vue but underthehood: Part 2 - The Language Engine
