Javascript is required
Mokkapps LogoMichael Hoffmann

Vue Tip: Destructure Props in Composition API Without Losing Reactivity

Michael Hoffmann (Mokkapps) - Senior Frontend Developer (Freelancer)
Michael Hoffmann
Jan 26, 2023
1 min read
Vue Tip: Destructure Props in Composition API Without Losing Reactivity Image
New Vue & Nuxt tips delivered to your inbox:

Inside <script setup> we use the defineProps() compiler macro to access props:

<script setup lang="ts">const props = defineProps<{ count: number }>()</script>

defineProps is a compiler macro and does not need to be imported.

As we all love destructuring objects in JavaScript you might want to try to destructure the props object:

<script setup lang="ts">const { count } = defineProps<{ count: number }>()</script>

When you destructure the props object the reactivity is lost.

By destructuring the props object, the count variable becomes a primitive value (in our case of type number) and is no longer a ref or reactive object.

You can try it yourself in the following StackBlitz demo. Click the "Increment" button multiple times and you will see that the double count value is not updated and always shows 0:

The simplest solution is to access props as props.count in order to retain reactivity:

<script setup lang="ts">import { computed } from 'vue'const props = defineProps<{ count: number }>()const doubleCount = computed(() => props.count * 2)</script><template>Double Count: {{ doubleCount }}</template>

Try it yourself, now the double count is correctly increased if the "Increment" button is clicked:

If you cannot live without destructuring Vue provides a special helper toRefs:

<script setup lang="ts">import { computed, toRefs } from 'vue'const props = defineProps<{ count: number }>()const { count } = toRefs(props)const doubleCount = computed(() => count.value * 2)</script><template>Double Count: {{ doubleCount }}</template>

toRefs(props) converts a reactive object (in this example props) to a plain object where each property of the resulting object is a ref pointing to the corresponding property of the original object. We need to use count.value inside the computed property, as it is a ref.

Here's the StackBlitz demo for toRefs:

You can also watch the corresponding video:

If you liked this Vue tip, follow me on Twitter to get notified about new tips, blog posts, and more. Alternatively (or additionally), you can subscribe to my weekly Vue newsletter.