Vue 3 Reactive System Core Implementations
Vue 3 achieves reactive data binding primarily through two ES6+ features:
- Proxy API: Enables interception of any property operation on target objects, including reads, writes, additions, and deletions—addressing Vue 2’s defineProperty-based limitasions like unresponsiveness to new/deleted properties.
- Reflect API: Provides standardized methods for performing default operations on target objects within proxy traps, ensuring compatibility and consistency.
const userState = { userName: "default", age: 25, id: 1001 };
const reactiveState = new Proxy(userState, {
// Intercept property read operations
get(target, key) {
return Reflect.get(target, key);
},
// Intercept property write or addition operations
set(target, key, value) {
return Reflect.set(target, key, value);
},
// Intercept property deletion operations
deleteProperty(target, key) {
return Reflect.deleteProperty(target, key);
}
});
reactiveState.userName = "Alice";
delete reactiveState.id;
Note that the Proxy/Reflect approach introduces minor compatibility isues with legacy browsers that lack ES6+ support.
Vue 3 Reactive Type Detection Functions
Vue 3 provides four built-in functions to identify reactive data types:
isRef: Checks if a value is arefobject (which wraps primitive values for reactivity).isReactive: Verifies if an object is a reactive proxy created withreactive().isReadonly: Determines if an object is a read-only proxy generated byreadonly().isProxy: Checks if an object is a proxy created by eitherreactive()orreadonly().
Setup Hook Usage in Vue 3
The setup() function serves as the entry point for Vue 3’s Composition API, running before the component instance is fully created. It takes two parameters: props (the component’s received props, reactive) and context (a non-reactive context object with utility properties/methods).
import { toRefs, toRef } from "vue";
setup(props, context) {
/******** Props Handling (Reactive) ********/
// Access props directly to retain reactivity (destructuring breaks it)
console.log(props.productName);
// Convert entire props to ref-wrapped properties and destructure
const { productName, price } = toRefs(props);
console.log(productName.value, price.value);
// Convert a single prop to a standalone ref
const quantity = toRef(props, "quantity");
console.log(quantity.value);
/******** Context Object Properties ********/
// Transmitted Attributes (non-reactive, equivalent to $attrs)
console.log(context.attrs);
// Component Slots (non-reactive, equivalent to $slots)
console.log(context.slots);
// Event Emitter (function, equivalent to $emit)
console.log(context.emit);
// Expose Public Properties (function to control component exposure)
console.log(context.expose);
}