Vue.js is a popular JavaScript framework known for its simplicity and flexibility, enabling developers to build interactive and dynamic web applications efficiently. However, like any technology, it comes with its learning curve and potential pitfalls.
In this blog article, we will explore some common mistakes developers make when working with Vue.js and provide practical advice on how to avoid them.
If you’d like even more tips on this subject, along with guided explanations and code samples checkout our course Common Vue.js Mistakes and How to Avoid Them. It’s a super valuable resource for junior and senior developers alike.
Problem: One of the core features of Vue.js is its reactivity system, which updates the view automatically when the state changes. On common mistake I see more junior developers make, is relying on non-reactive data and expecting mutations of that data to trigger updates. For example, this is a real piece of code I’ve seen in production:
const cookiesAccepted = computed(()=>{
return localStorage.getItem("cookieConsent")
})
The problem? We’re relying on a non-reactive dependency to provide the value for this computed property.
Solution: Ensure you alway rely on reactive data defined with reactive
or ref
when you expect changes to trigger component updates. If working with native browser API’s like localStorage, use a composable that wraps the API in a reactivity layer like useLocalStorage
from VueUse.
Problem: Computed properties are a powerful feature in Vue.js for creating dynamic values that change based on other data properties. A common mistake is using methods instead of computed properties for values that depend on other reactive data, which can lead to unnecessary computations and performance issues.
Solution: If a value needs to be recalculated based on reactive data changes, use a computed property. This ensures the calculation is cached and only re-evaluated when the dependencies change, improving app performance.
Problem: When they exist on the same node, v-if
has a higher priority than v-for
. That means the v-if
condition will not have access to variables from the scope of the v-for
.
<!--
This will throw an error because property "todo"
is not defined on instance.
-->
<li v-for="todo in todos" v-if="!todo.isComplete">
{{ todo.name }}
</li>
Solution: When possible, apply v-if
on a nested element or use computed properties to filter the data before looping through it with v-for
. This approach improves readability and ensures your v-if
has access to each individual item.
<template v-for="todo in todos">
<li v-if="!todo.isComplete">
{{ todo.name }}
</li>
</template>
<!-- or -->
<template v-for="todo in completedTodosComputedProp">
<li>{{ todo.name }}</li>
</template>
Problem: Vue's component system is designed to help developers organize and reuse code. A mistake often made is not breaking the application into smaller, reusable components, leading to code duplication and an unorganized codebase that's hard to maintain.
Solution: Identify parts of your application that can be isolated or reused and convert them into components. This not only makes your codebase more manageable and maintainable but also leverages Vue's reactivity and lifecycle hooks more effectively. You can also break up stateful functionality that doesn’t render anything into re-usable composables.
Problem: When using custom events, intervals, listeners for server events, or third-party libraries, developers sometimes forget to clean up these on going effects leading to memory leaks and performance issues, especially in Single Page Applications (SPAs). Take this component responsible for showing the current time.
<!-- Now.vue -->
<script setup>
import { ref } from 'vue';
const now = ref(new Date().toLocaleString());
setInterval(() => {
now.value = new Date().toLocaleString();
}, 1000);
</script>
<template>
{{ now }}
</template>
If it is ever removed from the page, the interval will continue ticking away even though it is no longer in use.
Solution: Always remove event listeners and stop intervals or timeouts in the unmounted
lifecycle hook. This ensures that components clean up after themselves and do not leave unnecessary operations running in the background.
onUnmounted(() => clearInterval(interval));
Alternatively, you can employ the help of useful libraries like VueUse that automatically clean up such sideffects based on common needs. (See the VueUse function useNow.)
Vue.js offers a robust platform for building web applications, but avoiding common pitfalls is key to harnessing its full potential. By understanding and addressing these common mistakes, developers can write more efficient, maintainable, and performant Vue applications. Remember, learning from mistakes is part of the journey in software development. The Vue School course on avoiding common Vue.js mistakes is an excellent resource to deepen your understanding and improve your skills in Vue.js development. It dives into some of the mistakes discussed here plus a lot more. Oh, and did we mention it’s 100% FREE! Check it out today!
Our goal is to be the number one source of Vue.js knowledge for all skill levels. We offer the knowledge of our industry leaders through awesome video courses for a ridiculously low price.
More than 200.000 users have already joined us. You are welcome too!
© All rights reserved. Made with ❤️ by BitterBrains, Inc.