·
1 min read

Vue Tip: Optimize Performance Using shallowRef

MH

Michael Hoffmann

@mokkapps

Vue Tip: Optimize Performance Using shallowRef Image

shallowRef can be used to optimize the reactivity of your Vue application. As you might have guessed, shallowRef is a shallow version of ref().

Let's start by defining a counter state using shallowRef:

Component.vue
<script setup lang="ts">
import { shallowRef } from 'vue'

const state = shallowRef({
  count: 0,
})
</script>

<template>
  <span>Count: {{ state.count }}</span>
</template>

Now let's try to modify the count value:

Component.vue
<script setup lang="ts">
import { shallowRef, watch } from 'vue'

const state = shallowRef({
  count: 0,
})

const increment = () => {
  state.value.count = 2 // ⚠️ doesn't trigger change (watcher & UI update)
}

watch(state, (newState) => {
  console.log('new state', newState)
})
</script>

<template>
  <span>Count: {{ state.count }}</span>
  <button @click="increment">Increment count</button>
</template>
If you click the "Increment count" button the counter in the UI is not updated and the watcher is not fired.

Unlike ref(), the inner value of a shallow ref is stored and exposed as-is, and will not be made deeply reactive. Only the .value access is reactive.

The reactivity is correctly triggered if we pass a complete new value to the .value property:

Component.vue
<script setup lang="ts">
import { shallowRef, watch } from 'vue'

const state = shallowRef({
  count: 0,
})

const setNewValue = () => {
  state.value = { count: 2 } // triggers change
}

watch(state, (newState) => {
  console.log('new state', newState)
})
</script>

<template>
  <span>Count: {{ state.count }}</span>
  <button @click="setNewValue">Set new .value</button>
</template>

shallowRef() is typically used for performance optimizations of large data structures, or integration with external state management systems.

Try it yourself in the following StackBlitz project:

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

I will never share any of your personal data. You can unsubscribe at any time.