Loading...

Vue 3.5+: How to Destructure Props in 2024 (Composition API)

Last update: 9/24/2024
Vue 3.5+: How to Destructure Props in 2024 title image

Introduction

Directly destructuring props containing reactive states wasn't feasible in versions of Vue below 3.5.0 because Vue would lose track of changes to the props. To avoid this, developers had to either use the toRefs() helper function to safely destructure props, or had to access the props directly through props.key. However, with Vue 3.5.0 and later versions, destructuring props is now possible without loosing reactivity.

In This Guide

This guide demonstrates how to destructure props in Vue 3.5+ and higher by implementing a simple counter. It also covers the alternative methods using toRefs() helper function and direct access through the props object for Vue versions below 3.5.0. The Composition API and the <script setup> syntax are used throughout this guide.

Setup

  • Vue 3.5.0
  • Vite 5.4.2
  • Node.js 20.14.0

Prerequisites

  • Basic understanding of Vue 3, the Composition API and the <script setup> syntax.
  • Node.js is installed on your machine
  • A fresh Vue 3 project (version 3.5.0 or higher)

Destructuring props in Vue 3.5.0 and Higher

Given a fresh Vue 3 project, we implement a simple counter. Update the <App> component as follows:

App.vue
<script setup lang="ts">
import ExponentialCount from "@/components/ExponentialCount.vue";
import { ref } from "vue";

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

<template>
  <div>
    Single count: {{ count }}
    <ExponentialCount :single-count="count"/>
    <button @click="count++">increment</button>
  </div>
</template>

Explanation of App.vue

  1. A reactive state count is declared with an initial value of 0 (line 5).
  2. Each time the <button> is clicked, the value of count is incremented by the handler (line 12).
  3. The value of count is displayed in the template and updates automatically (line 10).
  4. The reactive state count is passed to the custom child component <ExponentialCount :single-count="count"> (line 11). Since count is not a static value, : is prepended to the prop name.

Next, create a new file ExponentialCount.vue in the components/ directory with the following code:

ExponentialCount.cue
<script setup lang="ts">
import { computed } from 'vue';

const { singleCount } = defineProps<{ singleCount: number }>();
const exponentialCount = computed(() => singleCount * 2);
</script>

<template>
  <div>
    Exponential count: {{ exponentialCount }}
  </div>
</template>

Explanation of ExponentialCount.vue

  1. The singleCount prop is destuctured from defineProps(…) (line 4), instead of assigning it to a variable (such as const props = defineProps(…);}). In Vue versions below 3.5.0 singleCount would now lose reactivity.
  2. To illustrated reactivity is maintained, the reactive state singleCount is raising by the power of two (line 5) and assigned to exponentialCount.
  3. exponentialCountis displayed in the template (line 10).

In Vue 3.5.0 and higher, destructuring singleCount directly like this doesn’t lose reactivity. Each time the increment button is clicked, the reactive state in count is incremented and passed to the child component, where it is destructured without losing reactivity.

Destructuing Props in Vue below 3.5.0

In Vue below 3.5.0 destructuring props would still break reactivity. It is therefore necessary to assign props to a variable for direct access of to make use of the toRefs() helper function.

Accessing the props Object Directly

ExponentialCoun.vue
<script setup lang="ts">
import { computed } from 'vue';

const props = defineProps<{ singleCount: number }>();
const exponentialCount = computed(() => props.singleCount * 2);
</script>

<template>
  <div>
    Exponential count: {{ exponentialCount }}
  </div>
</template>

Here, the props are assigned to a variable (line 4) which can then be accessed by props.singleCount (line 5).

Destructuring props with toRefs()

Alternatively, the toRefs() helper function can be used to destructure props without loosing reactivity:

ExponentialCount.vue
<script setup lang="ts">
import { computed, toRefs } from 'vue';

const props = defineProps<{ singleCount: number }>();

const { singleCount } = toRefs(props);

const exponentialCount = computed(() => singleCount.value ** 2);
</script>

<template>
  <div>
    Exonential count: {{ exponentialCount }}
  </div>
</template>

The toRefs() function converts the reactive object props into a plain object, whereby each of its properties is ref pointing to the corresponding property of the original reactive object (documentation .

Summary

Starting from Vue 3.5.0, destructuring props no longer breaks reactivity, making it easier to work with props in a clean and concise way. In versions below 3.5.0, it is still necessary to destructure props with toRefs() or by accessing it via the props object, to keep reactivity. This guide demonstrated both approaches using a simple counter example.

Report a problem (E-Mail)