v-once is a directive in Vue.js used when you want to render a value only once. Even if the value of the property changes in the future, the value under v-once does not change once the initial render is complete.

Let’s look at an example to understand it better. To demonstrate the usage of v-once we will create a counter app that will increase the count by 1 every time a button is clicked.

<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <title>Vue.Js</title>
  </head>

  <body>
    <div id="app">
      <button v-on:click="counter()">Increment</button>
      <p>Initial Value: {{count}}</p>
      <p>Current Value: {{count}}</p>
    </div>
  </body>

  <script>
    const { createApp } = Vue;

    createApp({
      data() {
        return {
          count: 10,
        };
      },
      methods: {
        counter() {
          this.count++;
        },
      },
    }).mount("#app");
  </script>
</html>

v-once-vue-1

<button v-on:click="counter()">Increment</button>
<p>Initial Value: {{count}}</p>
<p>Current Value: {{count}}</p>

In this example, we want to show the initial value and also the latest value of count. Every time the user clicks the button, we will call the counter() which will increase the count by 1.

createApp({
  data() {
    return {
      count: 10,
    };
  },
  methods: {
    counter() {
      this.count++;
    },
  },
}).mount("#app");

The initial value of the count is set to 10.

Of course, once you click the button both the initial and the current value text will change.

v-once-vue-3

But we want the initial value to remain the same. This is where v-once directive comes into the picture. Let’s add v-once to our code.

<p v-once>Initial Value: {{ count }}</p>

So the entire code now looks like this:

<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <title>Vue.Js</title>
  </head>

  <body>
    <div id="app">
      <button v-on:click="counter()">Increment</button>
      <p v-once>Initial Value: {{count}}</p>
      <p>Current Value: {{count}}</p>
    </div>
  </body>

  <script>
    const { createApp } = Vue;

    createApp({
      data() {
        return {
          count: 10,
        };
      },
      methods: {
        counter() {
          this.count++;
        },
      },
    }).mount("#app");
  </script>
</html>

Using v-once the initial value text will remain the same irrespective of any changes in count property.

v-once-vue-4

v-once-vue-5

Using v-once you can avoid re-rendering of content which can help optimize the application depending on the use case.