How Does The ref() Method Work?
As explained earlier, the ref() method makes the standalone primitive value reactive.
The ref() method returns an object. The object contains only one property named value.
We can see this in the example below.
Here we are trying to console log the ref() method so that we can see what it returns as an object.
<template>
<h1>Coding Ninjas</h1>
</template>
<script>
import {ref} from 'vue'
export default {
name: 'App',
setup(){
const count = ref(10);
console.log(count)
return{
count
}
}
}
</script>
Output:
In the console, we can see the ref() is returning an object which contains a value property through which we can modify the contents and achieve Reactivity.

Now let us see how the contents on the front-end can be modified using ref().
We are not modifying anything in the code below and simply rendering the fname & lname
<template>
<h1>{{fname}} {{lname}}</h1>
</template>
<script>
import {ref} from 'vue'
export default {
name: 'App',
setup(){
const fname = ref('Coding');
const lname = ref('Enthusiast');
return{
fname,
lname
}
}
}
</script>
Output:

Let us now try to modify the lname and change lname = Ninjas. Do you think it will change in the front-end as well? Let's see.
<template>
<h1>{{fname}} {{lname}}</h1>
</template>
<script>
import {ref} from 'vue'
export default {
name: 'App',
setup(){
const fname = ref('Coding');
const lname = ref('Enthusiast');
//modifying the lname
lname.value = 'Ninjas';
return{
fname,
lname
}
}
}
</script>
Output:
Yes, the lname value is updated to Ninjas, which means the lname property is reactive.

How Does The reactive() Method Work?
We are already familiar with the ref() method and know how it works. It's time to get acquainted with the reactive() method, which also makes the javascript contents reactive and lets them modify & reflect in the front-end.
Let's see how we can create a reactive state using the reactive() method.
We are not modifying anything in the code below and simply rendering the fname & lname. We can also see that the reactive() method takes an object as an argument.
<template>
<h1>{{state.fname}} {{state.lname}}</h1>
</template>
<script>
import {reactive} from 'vue'
export default {
name: 'App',
setup(){
const state = reactive({
fname:'Coding',
lname:'Enthusiast'
})
return{
state
}
}
}
</script>
Output:

Let us now try to modify the lname and change lname = Ninjas. Do you think it will change in the front-end as well? Let's see.
<template>
<h1>{{state.fname}} {{state.lname}}</h1>
</template>
<script>
import {reactive} from 'vue'
export default {
name: 'App',
setup(){
const state = reactive({
fname:'Coding',
lname:'Enthusiast'
})
//modifying the lname
state.lname = 'Ninjas'
return{
state
}
}
}
</script>
Output:
Yes, the lname value has been updated to Ninjas, which means that the lname property is reactive.

Destructuring Reactive State
Sometimes we want to use a few properties from the large reactive object. In that case, we can do object destructuring to get the property we want.
For example, In the below code, we want to render only the fname & lname. In that case, we will use object destructuring.
<template>
<h1>{{fname}} {{lname}}</h1>
</template>
<script>
import {reactive} from 'vue'
export default {
name: 'App',
setup(){
const state = reactive({
fname:'Coding',
lname:'Enthusiast',
address:'Delhi',
country:'India'
})
//object destructuring
let {fname,lname} = state;
return{
fname,
lname
}
}
}
</script>
But there is a considerable drawback of doing object destructuring only with reactive().
Unfortunately, the reactivity for destructured properties would be lost.
In the above code, the fname & lname has lost their reactivity and have no effect upon updating or changing their values.
Let's see this.
<template>
<h1>{{fname}} {{lname}}</h1>
</template>
<script>
import {reactive} from 'vue'
export default {
name: 'App',
setup(){
const state = reactive({
fname:'Coding',
lname:'Enthusiast',
address:'Delhi',
country:'India'
})
//object destructuring
let {fname,lname} = state;
//modifying the lname
state.lname = 'Ninjas'
return{
fname,
lname
}
}
}
</script>
Output:
We are still getting the same output, and the lname has not been modified because the fname and lname have lost their reactivity due to destructuring.

Using reactive() With toRefs()
To solve the problem of destructuring so that the properties will not lose their reactivity upon destructuring, we can use the toRefs() function.
toRefs() function converts the reactive object to a set of refs. And these refs will retain the reactive connection to the source object.
From the below example, we can see that.
<template>
<h1>{{fname}} {{lname}}</h1>
</template>
<script>
import {reactive, toRefs} from 'vue'
export default {
name: 'App',
setup(){
const state = reactive({
fname:'Coding',
lname:'Geeks',
address:'Delhi',
country:'India'
})
//object destructuring
let {fname,lname} = toRefs(state)
//modifying the lname
state.lname = 'Ninjas'
return{
fname,
lname
}
}
}
</script>
Output:
Here we can see that lname remains reactive and updated to the value Ninjas, and we get the desired output.

FAQs
-
Difference between reactive() and ref()?
Since both the reactive() and ref() methods are used to achieve the reactive state in Vue. The significant difference is that ref() takes primitive values (like a number, string, boolean) and reactive() takes an object as an argument.
-
Use of toRefs()?
toRefs() function is used in case of object destructuring. It will ensure that the object's properties do not lose their reactive state.
-
Are Vue data reactive?
Yes, data is reactive in Vue. It is internally made reactive by reactive().
Key Takeaways
This article taught about Reactivity Fundamentals and different methods to create reactive states in Vue.
If you want to read more exciting web development blogs, you can visit Coding Ninjas Web Blogs.
Happy Learning!!