Telerik blogs

Cause Vue components to re-render via reactive variable values. Learn how in this post.

Sometimes we need our Vue components to re-render; however, Vue might not always re-render our components as we expect or when we want it to.

In this article, we will look at how to force a Vue component to re-render using reactive variables.

Vue’s Reactivity

Vue components will re-render if we update the values in reactive variables.

For instance, we write:

<script setup lang="ts">
import { ref } from "vue";

const count = ref(0);
</script>

<template>
  <div class="card">
    <button type="button" @click="count++">count is {{ count }}</button>
  </div>
</template>

to define the count reactive variable and set its initial value to 0 by calling ref.

Then we add a click event listener to the button to increment count's value. As a result, when we click the button, count is incremented by 1.

The ref function is used to define a reactive state in the Vue Composition API, which triggers the component to rerender when what it returns changes value.

To do the same thing with the Vue Options API, we declare a reactive value by putting it in the object returned by the data method.

For instance, we write:

<script>
export default {
  data() {
    return {
      count: 0,
    };
  },
};
</script>

<template>
  <div class="card">
    <button type="button" @click="count++">count is {{ count }}</button>
  </div>
</template>

We put count in the object returned by the data method and set its initial value to 0. And in the button, we do the same thing as before to increment count by 1 when we click on it.

In Vue 3, all reactive values are wrapped in a proxy object and Vue watches for changes in the proxy changes to detect changes within reactive values.

JavaScript proxies let us intercept and redefine fundamental operations for the object we create a proxy from.

To create a JavaScript proxy, we use the Proxy constructor. For instance, we write:

const target = {
  message1: "hello",
  message2: "everyone",
};

const handler = {
  get(target, prop, receiver) {
    console.log("get", target, prop);
    return target[prop];
  },
  set(obj, prop, value) {
    console.log("set", obj, prop, value);
    return Reflect.set(obj, prop, value);
  },
};

const proxy = new Proxy(target, handler);
console.log(proxy.message1);
proxy.message2 = "world";
console.log(proxy.message2);

to create the target object which we create a proxy from. Then we use the Proxy constructor to create a proxy object for target.

The handler object has the get and set methods, which intercept the operation for getting property values and setting them, respectively.

In the get method, we return the target[prop], which is the value of the prop property in the object. prop has the property name string, and target is the target object we created the proxy from.

In set, we call Reflect.set to set the obj value’s prop property to the value value. obj is the object we created the proxy from, and prop is the string with the property name. value is the value we are setting the object property to.

From the console logs, we can see get is called when we try to get any property value from the proxy object. And when we set the property in a proxy object, the set method is called.

We can change what’s returned by get and set to change the operations of getting and setting object property values.

For instance, we write:

const target = {
  message1: "hello",
  message2: "everyone",
};

const handler = {
  get(target, prop, receiver) {
    return `foo ${target[prop]}`;
  },
  set(obj, prop, value) {
    return Reflect.set(obj, prop, "bar");
  },
};

const proxy = new Proxy(target, handler);
console.log(proxy.message1);
proxy.message2 = "world";
console.log(proxy.message2);

to return a string with foo before the property value in the get method. And we set whatever property value we set in the proxy to 'bar'. As a result, we see "foo hello" and "foo bar" from the two console logs, respectively.

Vue 3 uses proxies for watching reactive value changes. Therefore, it can watch for deeply nested changes in property values without us doing any extra work.

For instance, we write:

<script setup lang="ts">
import { ref } from "vue";

const nestCount = ref({ nested: { count: 0 } });

const incrementDeeply = () => {
  nestCount.value.nested.count++;
};
</script>

<template>
  <div class="card">
    <button type="button" @click="incrementDeeply">
      count is {{ nestCount.nested.count }}
    </button>
  </div>
</template>

to define the incrementDeeply function. In it, we just increment the nested.count property value directly.

This works because Vue uses JavaScript proxies to watch for deeply nested changes. So it can pick up the change to nested.count immediately with the proxy and re-render component by watching the proxy set method’s changes.

With the Options API, we write:

<template>
  <button type="button" @click="incrementDeeply">
    count is {{ nestCount.nested.count }}
  </button>
</template>

<script>
export default {
  data() {
    return {
      nestCount: {
        nested: { count: 0 },
      },
    };
  },
  methods: {
    incrementDeeply() {
      this.nestCount.nested.count++;
    },
  },
};
</script>

In the data method, we define the nestCount reactive property. Inside it, we add the nested.count property and set it to 0 initially.

Then we define the incrementDeeply method and this.nestCount.nested.count increases by 1 when we call it. And we add a click event listener to the button and call incrementDeeply when we click it.

Because of Vue 3’s use of proxies to watch for changes, we can just set the deeply nested property’s value and it will re-render the component as a result.

Therefore, to make sure a Vue component re-renders when we want to, we should update the values of reactive variables.

Conclusion

We can get Vue components to re-render when we want to by updating the values of reactive variables.

Vue 3 should be able to watch for values in reactive values that are deeply nested objects because of its use of JavaScript proxies to watch for reactive value changes.


Vue
About the Author

John Au-Yeung

John Au-Yeung is a frontend developer with 6+ years of experience. He is an avid blogger (visit his site at https://thewebdev.info/) and the author of Vue.js 3 By Example.

Related Posts

Comments

Comments are disabled in preview mode.