Frontend DevelopmentVueJs Tutorials

Learn About Vue 3 Reactivity with ref and reactive

Learn About Vue 3 Reactivity with ref and reactive

Vue 3 introduced the Composition API, giving us powerful tools (ref, reactive, computed, watch, etc.) to manage state in a more flexible way. At the core of this is reactivity: Vue automatically tracks changes to data and updates the DOM.

 

 

Two of the most important APIs are:

  • ref() → makes a single value reactive.

  • reactive() → makes an object (or array) reactive.

Let’s dive in.

 

1. ref(): Reactive Primitive Values

ref is used when you want to make a single value reactive (string, number, boolean, or even objects if you prefer).

 
<script setup>
import { ref } from 'vue'

const count = ref(0)

function increment() {
  count.value++
}
</script>

<template>
  <button @click="increment">Count is: {{ count }}</button>
</template>

Key points:

  • You access the wrapped value using .value.

  • Vue automatically unwraps refs in templates, so you don’t write count.value in the <template>, just count.

 

2. reactive(): Reactive Objects

When you have an object or array with multiple properties, reactive is often more convenient.

 
<script setup>
import { reactive } from 'vue'

const user = reactive({
  name: 'Alice',
  age: 25,
})

function growOlder() {
  user.age++
}
</script>

<template>
  <p>{{ user.name }} is {{ user.age }} years old.</p>
  <button @click="growOlder">Grow Older</button>
</template>

Key points:

  • You access the wrapped value using .value.

  • Vue automatically unwraps refs in templates, so you don’t write count.value in the <template>, just count.

 

3. ref() with Objects

You can wrap objects with ref. Vue will still make them reactive, but you’ll need .value to access the object.

<script setup>
import { ref } from 'vue'

const book = ref({
  title: 'Vue 3 Guide',
  pages: 100,
})

function addPage() {
  book.value.pages++
}
</script>

<template>
  <p>{{ book.title }} - {{ book.pages }} pages</p>
  <button @click="addPage">Add Page</button>
</template>

Use ref() for primitives and reactive() for objects, unless you need to replace the entire object later (in that case, ref is better).

 

4. ref vs reactive – When to Use?

  • Use ref for primitives (numbers, strings, booleans).

  • Use reactive for objects and arrays with many properties.

  • Use ref for objects if you need to reassign/replace them entirely.

// Good: reassigning entire object
const settings = ref({ darkMode: false })
settings.value = { darkMode: true } // Works

// With reactive, reassigning breaks reactivity:
const prefs = reactive({ darkMode: false })
prefs = { darkMode: true } // ❌ Not reactive anymore

As you be aware that reassigning entire object with reactive breaks reactivity, you can use ref() or if using reactive try mutating specific object keys like so:

const prefs = reactive({ theme: { darkMode: false } }) 

prefs.theme = { darkMode: true }

 

5. Watching Changes

Sometimes you need to run code when a reactive value changes. With vue 3 watch.

<script setup>
import { ref, watch } from 'vue'

const name = ref('Alice')

watch(name, (newVal, oldVal) => {
  console.log(`Name changed from ${oldVal} to ${newVal}`)
})
</script>

For objects use a callback as watch source:

<script setup>
import { reactive, watch } from 'vue'

const user = reactive({ name: 'Alice', age: 25 })

watch(() => user.age, (newAge) => {
  console.log(`User is now ${newAge}`)
})
</script>

 

6. Combining ref and reactive

You can mix them. For example, a reactive object holding multiple refs:

<script setup>
import { ref, reactive } from 'vue'

const tasks = reactive({
  items: [],
  loading: ref(false),
})

function addTask(name) {
  tasks.items.push({ name, done: false })
}
</script>

<template>
  <button @click="addTask('Learn Vue')">Add Task</button>
  <p v-if="tasks.loading">Loading...</p>
  <ul>
    <li v-for="task in tasks.items" :key="task.name">{{ task.name }}</li>
  </ul>
</template>

 

7. Common Pitfalls ⚠️

  • Forgetting .value
count++ // ❌ doesn’t work
count.value++ // ✅ works
  • Reassigning a reactive object
user = { name: 'Bob' } // ❌ breaks reactivity
Object.assign(user, { name: 'Bob' }) // ✅ keeps reactivity

 

 

0 0 votes
Article Rating

What's your reaction?

Excited
0
Happy
0
Not Sure
0
Confused
0

You may also like

Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments