Understanding Vue 3 Reactivity | by Anamol Soman
In depth explanation of vue 3 reactivity
Introduction
When Vue 3 was released, one of the most significant changes was its reactivity system. This system is the heart of Vue, enabling it to respond efficiently to changes in data and reflect those changes in the DOM. Whether you’re a seasoned Vue 2 developer or new to the Vue ecosystem, understanding how Vue 3’s reactivity works is crucial. In this blog, we’ll explore Vue 3’s reactivity in detail, focusing on how it works, why it’s powerful, and how you can use it effectively in your applications.
What is Reactivity?
In simple terms, reactivity is the concept of making objects reactive to changes. When a reactive property in an object is modified, any part of the UI that depends on that property will automatically update to reflect the change. Vue achieves this through a system of watchers and dependencies.
In Vue 2, reactivity was achieved using Object.defineProperty. However, Vue 3 introduces a more powerful and flexible reactivity system using JavaScript Proxies.
How Vue 3 Reactivity Works
1. Proxies: The Core of Reactivity
Vue 3’s reactivity is built on JavaScript’s Proxy API. A Proxy allows you to intercept and redefine fundamental operations for an object, such as property access, assignment, deletion, and more. This makes it ideal for implementing a reactivity system.
When you create a reactive object using Vue 3’s reactive
API, Vue internally wraps the object with a Proxy. Here's a simple example:
import { reactive } from 'vue';
const state = reactive({
count: 0,
});
// Accessing the property
console.log(state.count); // 0
// Modifying the property
state.count = 1;
console.log(state.count); // 1
Understanding Vue 3 Reactivity: A Gentle Dive
When Vue 3 was released, one of the most significant changes was its reactivity system. This system is the heart of Vue, enabling it to respond efficiently to changes in data and reflect those changes in the DOM. Whether you’re a seasoned Vue 2 developer or new to the Vue ecosystem, understanding how Vue 3’s reactivity works is crucial. In this blog, we’ll explore Vue 3’s reactivity in detail, focusing on how it works, why it’s powerful, and how you can use it effectively in your applications.
What is Reactivity?
In simple terms, reactivity is the concept of making objects reactive to changes. When a reactive property in an object is modified, any part of the UI that depends on that property will automatically update to reflect the change. Vue achieves this through a system of watchers and dependencies.
In Vue 2, reactivity was achieved using Object.defineProperty. However, Vue 3 introduces a more powerful and flexible reactivity system using JavaScript Proxies.
How Vue 3 Reactivity Works
1. Proxies: The Core of Reactivity
Vue 3’s reactivity is built on JavaScript’s Proxy API. A Proxy allows you to intercept and redefine fundamental operations for an object, such as property access, assignment, deletion, and more. This makes it ideal for implementing a reactivity system.
When you create a reactive object using Vue 3’s reactive
API, Vue internally wraps the object with a Proxy. Here's a simple example:
import { reactive } from 'vue';
const state = reactive({
count: 0,
});
// Accessing the property
console.log(state.count); // 0
// Modifying the property
state.count = 1;
console.log(state.count); // 1
In this example, state
is a reactive object. Any change to its properties will trigger updates wherever those properties are used.
2. Tracking and Triggering
Vue 3’s reactivity system is based on two main concepts: tracking and triggering.
- Tracking: When you access a property on a reactive object, Vue tracks which effect (a function that relies on this data) depends on it. This is done using a dependency tracking system.
- Triggering: When you modify a property, Vue knows which effects depend on that property and triggers them to update the UI or perform any other necessary side effects.
This tracking and triggering system is what allows Vue to efficiently update only the parts of the DOM that need to be updated, rather than re-rendering the entire component.
Creating Reactive Data: reactive
vs ref
Vue 3 provides two primary ways to create reactive data: reactive
and ref
.
1. reactive
: For Objects
The reactive
function is used to create a reactive object. It takes an object as an argument and returns a Proxy-wrapped version of that object.
import { reactive } from 'vue';
const state = reactive({
user: {
name: 'Anamol',
age: 28,
},
});
state.user.name = 'Soman';
console.log(state.user.name); // Soman
Here, state.user.name
is reactive, and any change to it will trigger updates.
2. ref
: For Primitive Values
While reactive
is excellent for objects, you might need to create reactive primitives (like strings, numbers, or booleans). This is where ref
comes into play.
import { ref } from 'vue';
const count = ref(0);
count.value++;
console.log(count.value); // 1
ref
creates a reactive reference to a primitive value. The value is accessed and modified via the .value
property.
Why ref
for Primitives?
You might wonder why Vue needs a special method for primitives. This is because primitive values (like numbers) are not objects and cannot be wrapped with a Proxy. Therefore, Vue uses ref
to create an object with a value
property, which can be made reactive.
Reactive vs. Non-Reactive Data
In Vue 3, you can mix reactive and non-reactive data within the same component. However, it’s essential to understand when to use each. For example, if you have data that doesn’t change or doesn’t need to trigger UI updates, you can use non-reactive data. This can be done simply by not wrapping it in reactive
or ref
.
const nonReactiveData = {
message: 'Hello, world!',
};
This data is not reactive, and Vue won’t track or trigger updates based on changes to it.
Computed Properties: Derived Reactive Data
In addition to reactive
and ref
, Vue 3 offers computed
properties. Computed properties are reactive, derived values that automatically update when their dependencies change. They're handy for encapsulating logic that involves reactive data.
import { reactive, computed } from 'vue';
const state = reactive({
firstName: 'Anamol',
lastName: 'Soman',
});
const fullName = computed(() => `${state.firstName} ${state.lastName}`);
console.log(fullName.value); // Anamol Soman
state.firstName = 'John';
console.log(fullName.value); // John Soman
Here, fullName
is a computed property that depends on state.firstName
and state.lastName
. Whenever either of these properties changes, fullName
will automatically update.
When to Use reactive
, ref
, and computed
reactive
: Use for complex objects and nested structures. It’s great for creating a state object that holds multiple properties.ref
: Best for single primitive values or when you want to create a reactive variable that can be reassigned.computed
: Ideal for creating derived state that depends on other reactive properties.
Vue 3 Reactivity in Composition API
The Composition API is one of the most notable features introduced in Vue 3. It provides a more flexible way to organize and reuse code, particularly in large applications.
Using reactive
and ref
in the Composition API looks like this:
import { reactive, ref } from 'vue';
export default {
setup() {
const state = reactive({
count: 0,
});
const doubleCount = computed(() => state.count * 2);
function increment() {
state.count++;
}
return {
state,
doubleCount,
increment,
};
},
};
In this example, we’ve created a reactive state
object and a computed doubleCount
property. The increment
function updates the count
, and thanks to Vue's reactivity system, doubleCount
will always reflect the correct value.
Conclusion
Vue 3’s reactivity system is a significant evolution from Vue 2, offering more power, flexibility, and efficiency. By leveraging Proxies, Vue 3 provides a more robust way to track changes and update the UI. Understanding when to use reactive
, ref
, and computed
is key to building effective and maintainable Vue applications.
Whether you’re working on small projects or large-scale applications, mastering Vue 3’s reactivity will undoubtedly enhance your development workflow and help you build dynamic, responsive UIs with ease. Happy coding!
“If you enjoyed my content, consider supporting my work by buying me a coffee on Ko-fi. Your contribution fuels my creativity and helps me keep producing quality content. Every coffee is deeply appreciated! Thanks for being an awesome supporter! Buy a Coffee”