Common Vue 3 Mistakes and How to Avoid Them

Vue 3 is powerful and flexible, but even experienced developers can run into common pitfalls. Here are some tips and tricks to help you avoid mistakes and write better Vue applications.

1. Forgetting to Use the ref or reactive API for Reactivity

The Problem:

Assigning primitive values directly without using ref or reactive leads to no reactivity.

// Incorrect
let count = 0;

// Updates won't trigger UI reactivity
count++;

The Solution:

Use ref for primitive values and reactive for objects.

import { ref } from 'vue'; 
const count = ref(0); 
count.value++; // Reactivity is maintained

2. Mutating Props Directly

The Problem:

Props are read-only. Mutating them directly breaks the unidirectional data flow and may cause errors.

// Incorrect
props.value = 'new value'; // Vue will warn you

The Solution:

Use emit to communicate changes to the parent or use a computed property for derived data.

const emitUpdate = () => emit('updateValue', newValue);

3. Using v-for Without a key

The Problem:

Omitting the key in v-for can lead to rendering issues and incorrect DOM updates.

<!-- Incorrect -->
<li v-for="item in items">{{ item.name }}</li>

The Solution:

Always provide a unique key for each item in the loop.

<!-- Correct -->
<li v-for="item in items" :key="item.id">{{ item.name }}</li>

4. Not Cleaning Up Side Effects

The Problem:

Forgetting to clean up watchers, event listeners, or intervals can cause memory leaks.

// Incorrect
watch(() => someValue, () => {
  console.log('Value changed');
});

The Solution:

Use onUnmounted or the cleanup function in watch.

import { onUnmounted, watch } from 'vue';

const stop = watch(() => someValue, () => {
  console.log('Value changed');
});

onUnmounted(() => stop()); // Clean up watcher

5. Not Using Template Conditionals Properly

The Problem:

Using both v-if and v-for on the same element can cause unexpected behavior.

<!-- Incorrect -->
<li v-for="item in items" v-if="item.visible">{{ item.name }}</li>

The Solution:

Use computed properties to filter data instead.

computed: {
  visibleItems() {
    return items.filter(item => item.visible);
  },
}

<li v-for="item in visibleItems" :key="item.id">{{ item.name }}</li>

6. Ignoring Performance Optimization

The Problem:

Rendering large lists or overusing watchers can lead to slow performance.

The Solution:

  • Use v-once for static content.
  • Use computed for derived data to avoid unnecessary re-computations.
  • Implement virtual scrolling for large lists using libraries like Vue Virtual Scroll List.

Conclusion

Avoiding these common mistakes can save you from unnecessary debugging and improve your Vue 3 application’s quality and performance. By following these best practices, you’ll write cleaner, more efficient code and create better experiences for your users.

Leave a comment

Your email address will not be published. Required fields are marked *