DEV Community

Cover image for Things that I like better in Vue than in React
Jaydev Mahadevan
Jaydev Mahadevan

Posted on • Updated on • Originally published at jaydevm.hashnode.dev

Things that I like better in Vue than in React

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

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?

Vue starter page

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>
Enter fullscreen mode Exit fullscreen mode

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>;
}
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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>
  );
}

Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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>;
}
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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>
  )
}
Enter fullscreen mode Exit fullscreen mode

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)

Collapse
 
fatihkurtl profile image
Fatih Kurt

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.

Collapse
 
dnmyers profile image
Daniel Myers

Is 2 years a typo?

Collapse
 
guteres007 profile image
Martin Andráši

I am Vue developer. For small projects is vue ok, but if you have long term projects.... vue is not, what you want.

Collapse
 
waleedtariq109 profile image
Waleed Tariq

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.

Collapse
 
fatihkurtl profile image
Fatih Kurt

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.

Collapse
 
rafaelmagalhaes profile image
Rafael Magalhaes • Edited

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

Collapse
 
aminnairi profile image
Amin

You forgot to clear the interval on your second point.

<template>
  <p>{{ count }}</p>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';

let interval;

const count = ref(0);

onMounted(() => {
  interval = setInterval(() => {
    count.value++;
  }, 1000);
});

onUmounted(() => {
  clearInterval(interval);
});
</script>
Enter fullscreen mode Exit fullscreen mode
Collapse
 
jaydevm profile image
Jaydev Mahadevan

Thanks for the code review :) Fixed.

Collapse
 
aminnairi profile image
Amin

You're welcome.

Not to seem a little bit picky, but you also forgot to store the interval variable in the Vue.js example.

Collapse
 
lundjrl profile image
James Robert Lund III

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:

  • React with it's resources (Meta, FOSS, etc) will continue to drive the trends
  • Vue will continue to improve on these trends

What do you think? Thanks for writing the article :)

Collapse
 
jaydevm profile image
Jaydev Mahadevan

I think Vue historically has improved from things React pioneered

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. :)

Collapse
 
dawosch profile image
Dawosch

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 :)

Thread Thread
 
nafaabout profile image
Nafaa Boutefer

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.

class Books < ApplicationController
   # Return all books
   # GET /books(.:format)
   def index
      @books = Book.all # can be filtered, paginated, and so on

      respond_to do |format|
           format.html # This expects to find a view under app/views/books/index.html.erb, erb a template engine that renders ruby inside html
           format.json # This expects to find a view under /app/views/books/index.json.jbuilder, jbuilder is just a json template engine than can render some ruby code to return json data
           format.xml
           .... and so on and so on
    end
Enter fullscreen mode Exit fullscreen mode

With this you can easily expose endpoints for different data formats.

Collapse
 
webjose profile image
José Pablo Ramírez Vargas

I'm on the Svelte boat, but my sentiment towards React is akin to this.

Collapse
 
gamadev profile image
Alex Maximiano

Hi!
Thank you for sharing this.

Collapse
 
lexlohr profile image
Alex Lohr

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.

Collapse
 
jaydevm profile image
Jaydev Mahadevan

100% agree - learning the fundamentals will always make you better. Great article btw!

Collapse
 
dnmyers profile image
Daniel Myers

1 - create-react-app isn't the recommended way to build react apps anymore anyway. I use Vite, personally

Collapse
 
walidov profile image
Waleed Asender

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!

Collapse
 
azimidev profile image
Amir Hassan Azimi

Nice blog

Collapse
 
shoaibjamil profile image
Shoaib Jamil

Its time to learn Vue too!