Vue Tip: Avoid Side Effects in Computed Properties
It is considered bad practice to introduce side effects inside computed properties and functions because it makes the code unpredictable and hard to understand.
What is a side effect? In the context of computed properties, a side effect is a modification of the state's global state or the internal component state.
Let's take a look at an example with side effects:
1<script setup lang="ts">
2import { computed, ref } from 'vue'
3
4const firstName = ref('Michael')
5const lastName = ref('Hoffmann')
6const array = ref([])
7
8const fullName = computed(() => {
9 firstName.value = 'Mike' // side effect
10 return `${firstName.value} ${lastName.value}`
11})
12
13const reversedArray = computed(() => array.value.reverse()) // side effect, original array is mutated
14</script>
Now let's change the code and remove the side effects:
1<script setup lang="ts">
2import { computed, ref } from 'vue'
3
4const firstName = ref('Michael')
5const lastName = ref('Hoffmann')
6const array = ref([])
7
8const fullName = computed(() => `${firstName.value} ${lastName.value}`)
9const reversedArray = computed(() => array.value.slice(0).reverse()) // .slice creates a copy of the array
10</script>
Read this fantastic article from Michael Thiessen for more details about side effects.
If you liked this Vue tip, follow me on X to get notified about new tips, blog posts, and more. Alternatively (or additionally), you can subscribe to my weekly Vue & Nuxt newsletter:
Vue Tip: Test Vue Components Using Vue Testing Library
Vue Testing Library is my preferred Vue.js testing library that encourages good testing practices.
Vue Tip: Typing Template Refs With TypeScript
Template refs only exist after the component is mounted. Thus, it’s necessary to type template refs with a union type that includes the DOM element type as well as null.