Using Reactivity in Vue 3


4 min read

Using Reactivity in Vue 3

In Vue 3, the reactivity system has been enhanced with the Composition API, providing more flexibility and control which keeps your UI in sync with your data. It allows developers to declaratively define relationships between data and the UI declaratively, ensuring that changes in data are automatically reflected in the UI and vice versa which removes the burden of manually managing UI updates based on data changes.

Ref() and Reactive():

In Vue 3, you can create reactive data structures using ref() for the primitive values and reactive() for the objects.

Ref() is calling reactive() behind the scenes since, reactive() works for objects and ref() calls reactive(), objects work for both but, ref() has a .value property for reassigning. Use ref() when it's a primitive (for example 'string', true, 23, etc). When you write ref([]) it is equivalent to ref(reactive([])). Any object (including an array) passed to ref will be passed to reactive internally.

Reactive() does not have .value and therefore cannot be reassigned. it only takes objects, not JS primitives (String, Boolean, Number, BigInt, Symbol, null, undefined). Use reactive() when it's an object you don't need to reassign, and you want to avoid the overhead of ref() .

In Summary, ref() seems like the way to go since it supports all object types and allows reassigning with .value. ref() is a good place to start, but as you get used to the API,you will know that reactive() has less overhead, and you may find it better meets your needs.

<script setup>

    import { ref, reactivity } from vue

    // ref
    const counter = ref(0);
    const users = reactive([
      { name: "user1", age: 20 },
      { name: "user2", age: 30 },


While ref() is suitable for primitive values, reactive() is ideal for complex objects, offering a comprehensive reactivity setup.

Computed properties

Computed properties are another cornerstone of reactivity in Vue.js 3. They act like derived data, calculated based on other reactive values. Whenever the data they depend on changes, computed properties automatically re-evaluate and update their values, ensuring your UI always displays the latest information.

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

    const firstName = ref('john')
    const lastName = ref('cena')

    const fullname = computed(() => `${firstName.value} + ${lastName.value}`)


Watchers allow you to observe changes in reactive properties and execute custom logic when those properties change. This mechanism is particularly useful when you need to perform specific actions in response to changes in your data.

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

    const obj = reactive({ count: 0 })

      () => obj.count,
      (newValue) => {
        console.log(`count is: ${newValue}`)

Unveiling the Magic Behind Vue.js 3 Reactivity

The reactivity system of Vue.js 3 is responsible for the dynamic nature of your application. It operates silently in the background to ensure that changes in your data are accurately reflected in the user interface, keeping everything in sync and providing an interactive user experience. However, have you ever wondered how this magic happens?

Vue uses JavaScript Proxies to create an intelligent observation layer around your data. These Proxies work as silent guards, intercepting all interactions with your reactive data, which are objects or values wrapped with. Whenever a change occurs, such as adding a property, modifying an existing one, or deleting something entirely, the Proxies immediately act to handle it.

The update process unfolds in a series of well-coordinated steps:

  1. Proxy Detects Change: The Proxy observes a modification in your reactive data.

  2. Dependency Collection: The Proxy meticulously identifies all parts of your application that depend on the changed data. This includes template expressions referencing the data and computed properties deriving their values from it.

  3. Scheduler Steps: To optimize performance, Vue employs a scheduler. It groups multiple changes together and triggers a single update cycle, preventing unnecessary re-renders, especially during rapid data manipulation.

  4. UI Re-renders: Finally, Vue utilizes the collected dependency information to efficiently update the DOM with the new data, ensuring your UI reflects the latest information.

Let's see this in action with a simple code example:

<script setup>
  import { ref } from vue    
  const count = ref(0);

  const increment = () => {

    <p>You clicked {{ count }} times</p>
    <button @click="increment">Click me!</button>

Here, count is wrapped in, making it reactive. Clicking the button triggers the increment function, which increases count.value. The Proxy watching count detects this change. It then identifies the template expression {{ count }} as depending on count. Vue batches the change, updates the DOM, and the displayed count reflects the new value.


Reactivity is a fundamental concept in Vue 3 that enables seamless synchronization between data and the UI. You can build powerful and dynamic Vue applications by understanding the reactivity model, working with reactive data, and utilizing computed properties. However, itโ€™s important to know the reactivity caveats and follow best practices to ensure optimal reactivity and performance.