Middle
How does reactivity work in Vue.js?
sobes.tech AI
Answer from AI
Reactivity in Vue.js is based on the "Observer" pattern.
When a Vue instance is created, it walks through all properties in the data object and converts them into getters and setters using Object.defineProperty in Vue 2 or Proxy in Vue 3.
Vue 2:
- Accessing a property (getter) makes Vue track which component uses it.
- Changing a property (setter) notifies all components that depend on it to update (re-render the template).
Vue 3:
- Uses
Proxyto intercept all operations on the object (adding, deleting properties, changing values, etc.), providing more complete reactivity compared to Vue 2. - Thanks to
Proxy, Vue 3's reactivity has no limitations like Vue 2 (no need for$setto add new properties).
Key components of reactivity:
- Observer: Converts data properties into getters/setters (Vue 2) or handles them with Proxy (Vue 3).
- Dep (Dependency): An object associated with each reactive property that holds a list of dependent Watchers.
- Watcher: Represents a component, computed property, or watcher that depends on reactive data. When data changes, the Watcher is notified and triggers the appropriate action (e.g., re-rendering the component).
Example (Vue 2):
// Internal implementation (simplified)
function defineReactive(obj, key, val) {
let dep = new Dep(); // Create a Dep for the property
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get: function reactiveGetter() {
// If there is a global Watcher (during component rendering)
if (Dep.target) {
dep.depend(); // Add Watcher to Dep's dependency list
}
return val;
},
set: function reactiveSetter(newVal) {
if (newVal === val) return;
val = newVal;
dep.notify(); // Notify all dependent Watchers
}
});
}
// How it looks in a component
new Vue({
data: {
message: 'Hello' // defineReactive will be applied to message
},
template: '<div>{{ message }}</div>' // Accessing message will add the Watcher of this template to the message's Dep
});