I’ve been using React for a long time, so when some says “Hey, you should try a different frontend framework”, my answer is always pffft, but I’m already so efficient =P. There have been enough cool developments in Vue, though, to make me want to try it. And man was I pleasantly surprised! Vue has a bunch of neat features that make me jealous as React dev. Let's delve into some Vue patterns that stand out against React's approach!
1. Installation is Fun
The Vue’s out-of-the-box impressions is light-years ahead — npm create vue@latest
feels like a designed experience, while npm create-react-app
is just a plain ol’ NPM command. I prefer interactively selecting which packages to install, as done in Vue, over CRA’s process.
On top of that, the packages installed by Vue provide a more complete dev experience than CRA, covering areas like routing, state management, and code formatting.
Vue’s installation process is awesomely interactive.
Also, can we talk about how helpful the starter page is when you open localhost
for your new project?
All the Vue examples going forward are using the Composition API from Vue 3, which is most equivalent to functional React.
2. Intuitive Reactivity System
Vue's reactivity system feels more intuitive and less boilerplate-heavy compared to React's state management. Vue handles dependency tracking and updates automatically, making state management straightforward.
Vue Example
<template>
<p>{{ count }}</p>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
const count = ref(0);
onMounted(() => {
setInterval(() => {
count.value++;
}, 1000);
});
onUnmounted(() => clearInterval(interval));
</script>
React Equivalent
React requires more boilerplate to achieve similar reactivity, especially for effects and state updates that depend on previous state values. Who else has to look up the subtle differences between useEffect
, useMemo
, and useCallback
every time you want to use them? 🙋🏾♂️
function Counter() {
const [count, setCount] = React.useState(0);
React.useEffect(() => {
const interval = setInterval(() => {
setCount(currentCount => currentCount + 1);
}, 1000);
return () => clearInterval(interval);
}, []);
return <p>{count}</p>;
}
3. Single-File Components
Single-file components (SFCs) are definitely a love/hate thing, but I think they are great, especially for small components. In my opinion, encapsulating HTML, JavaScript, and CSS in one file promotes better organization and readability.
Vue Single File Component
<script setup lang="ts">
import { defineProps } from 'vue'
defineProps({
message: String
})
</script>
<template>
<div class="message-box">
<p>{{ message }}</p>
</div>
</template>
<style scoped>
.message-box {
padding: 20px;
border: 1px solid #eee;
}
</style>
React Equivalent
In React, achieving the same encapsulation typically involves separating concerns into different files or adopting CSS-in-JS libraries, which can add complexity.
function MessageBox({ message }) {
return (
<div className="message-box">
<p>{message}</p>
</div>
);
}
// CSS is managed separately or through CSS-in-JS solutions
4. Conditional Rendering
Vue's directive system (v-if
, v-for
, etc.) provides a more readable approach to conditional rendering than React. This advantage becomes more pronounced as your if/else statements become more complicated.
Vue Example with Directives
<script setup lang="ts">
import { ref } from 'vue';
const isSubscribed = ref(false);
const isSubscriptionExpiring = ref(true);
// Above properties updated dynamically...
</script>
<template>
<div>
<p v-if="!isSubscribed">Please subscribe to access premium features.</p>
<p v-else-if="isSubscriptionExpiring">Your subscription is expiring soon. Please renew to continue enjoying premium features.</p>
<p v-else>Welcome back, valued premium user!</p>
</div>
</template>
React Equivalent
function SubscriptionStatus() {
const isSubscribed = false;
const isSubscriptionExpiring = true;
// Above properties updated dynamically...
return (
<div>
{isSubscribed ? (
isSubscriptionExpiring ? (
<p>Your subscription is expiring soon. Please renew to continue enjoying premium features.</p>
) : (
<p>Welcome back, valued premium user!</p>
)
) : (
<p>Please subscribe to access premium features.</p>
)}
</div>
);
}
You can of course move the JSX-based logic into a JS function, but the initial pass is easier to understand in Vue.
5. Computed Properties
Vue's computed properties simplify the handling of complex logic that depends on reactive data. They are automatically cached and only re-evaluated when their dependencies change, optimizing performance.
Vue Example
<script setup lang="ts">
import { computed, ref } from 'vue'
const price = ref(10)
const quantity = ref(3)
const totalPrice = computed(() => price.value * quantity.value)
</script>
<template>
<p>Total price: {{ totalPrice }}</p>
</template>
React Equivalent
In React, similar functionality requires useMemo hook, adding complexity and verbosity to component logic.
function TotalPrice() {
const [price, setPrice] = React.useState(10);
const [quantity, setQuantity] = React.useState(3);
const totalPrice = React.useMemo(() => {
return price * quantity;
}, [price, quantity]);
return <p>Total price: {totalPrice}</p>;
}
6. Streamlined State Management
Pinia is one of the recommended state management solutions for Vue. Thanks to its tight integration with Vue and thoughtful API, it feels more streamlined than the equivalent code in React + Redux.
Vue with Pinia
// stores/counter.js
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
state: () => {
return { count: 0 }
},
actions: {
increment() {
this.count++
},
},
})
// components/MyCounter.vue
<script setup>
import { useCounterStore } from '@/stores/counter'
const counter = useCounterStore()
</script>
<template>
<button @click="counter.increment">Increment</button>
<div>Current Count: {{ counter.count }}</div>
</template>
React with Redux
// counterSlice.js
import { createSlice } from '@reduxjs/toolkit'
export const counterSlice = createSlice({
name: 'counter',
initialState: {
value: 0,
},
reducers: {
increment: (state) => {
state.value += 1
}
},
})
export const { increment } = counterSlice.actions
export default counterSlice.reducer
// Counter.js
import React from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { decrement, increment } from './counterSlice'
export function Counter() {
const count = useSelector((state) => state.counter.value)
const dispatch = useDispatch()
return (
<button onClick={() => dispatch(increment())}>
Increment
</button>
<span>{count}</span>
)
}
In Conclusion
My initial foray into learning Vue has expanded my perspectives on good design patterns and well-built APIs. It’s clear that Vue prioritized developer experience and application performance from the first commit. I think the biggest lesson here is that regardless of your skill level or what tools you have mastered, you can always learn from trying something new!
Is there anything else you like about Vue? Let me know in the comments!
PS. I share content like this post 2x / week. If you’re interested in frontend, backend, and how to become a better full stack developer, subscribe to my newsletter!
Top comments (21)
Believe me, I strongly recommend that you learn and use vue, you can produce projects much faster and simpler and get results, I have been dealing with software for 2 years, I have used svelte and react, but I have never seen such performance and simplicity as vue. Moreover, the easiest and most manageable state management among web frameworks is in vue.
Is 2 years a typo?
I am Vue developer. For small projects is vue ok, but if you have long term projects.... vue is not, what you want.
It's a myth among developers that Vue is only for small projects, but luckily, this myth has been debunked by Evan You (the creator of Vue). So, there is no such thing as Vue being just for small projects.
In fact, long-term and large projects are better managed with vue, for example, a large admin panel for a company was made by me and my friend together, both state management and code readability and coding speed were a great advantage for us.
What makes you say this? I have multiple large projects at work with nuxt 3 and never run into any problems that Vue couldn't handle
You forgot to clear the interval on your second point.
Thanks for the code review :) Fixed.
You're welcome.
Not to seem a little bit picky, but you also forgot to store the
interval
variable in the Vue.js example.In the same boat here, years of React but starting to use Vue more.
I think Vue historically has improved from things React pioneered, no?
Which to me brings two things:
What do you think? Thanks for writing the article :)
That was my feeling as I was learning Vue as well. Interestingly, the first versions of React and Vue came out around the same time. I think you can attribute part of it to the Vue team being able to learn from and improve on React's API, but it seems like they also have a different philosophy on how a developer API should look in general.
As a mature framework, React's patterns are more or less solidified. Lots of improvements have been released, but they are mostly under the hood.
I think React and Vue will both continue to evolve in a positive direction. As for trends and trendsetters, the cool kids have already moved on to new stuff like Svelte, Solid, HTMX, etc. :)
HTMX looks cool first, but when you think about the problems it‘s no option in my opinion.
The idea behind HTMX reaches back to ajax or like web development with Java and jsf.
This results in Monolithe like systems.
And the biggest problem for me is, that you want to have interfaces for your systems. And with interfaces I mean rest endpoints so that you can get the raw data you want and make different UIs with different technologies.
When you work with HTMX I bet you don’t create separate endpoints for your system so no other system can work with the data your Plattform produces.
I stick to react :)
I'm not sure I'd agree much with you in this regard. Exposing json endpoints could be a choice that might/might not be difficult depending on the way you built your backend. I use Ruby on Rails, and with that you can return a response to a request in whatever format is requested. All from the same route and from within the same place.
With this you can easily expose endpoints for different data formats.
I'm on the Svelte boat, but my sentiment towards React is akin to this.
Hi!
Thank you for sharing this.
I think you should learn the concepts behind those frameworks rather than one framework. Then you are free to choose whatever framework fits your current task best.
100% agree - learning the fundamentals will always make you better. Great article btw!
1 - create-react-app isn't the recommended way to build react apps anymore anyway. I use Vite, personally
I couldn't agree more! Another point where Vue has excelled over React is the learning community. React lacks platforms like VueMastery.com or VueSchool.com!
Nice blog
Its time to learn Vue too!