I work with Vue and React pretty much on a daily basis. My full-time job uses Vue and I have a few side projects the use React. This site is a Gatsby site so it was built using React. I also use Gatsby for other side projects. Truthfully I like both frameworks a lot. This article will cover their key differences and similarities.
Note: Vue 3 is production ready. I have researched the new features but I haven't upgraded any projects yet so any information about Vue 3 is based on research and not actual experience.
I'm not going to discuss Angular much because I have not used it in a production app.
Key Similarities
View Layer Only
Both React and Vue are tools for building the view layer of your application. This makes them very flexible. You can use either framework to build single-page or multi-page applications.
Component Based
React and Vue both use components as their primary building blocks. Both frameworks also allow nested components and props.
Flux Implementations
While they are not included in the core, both frameworks have Flux state management implementations.
JSX
Even though JSX is most associated with React you can use it with Vue. I have not personally used JSX with Vue.
Key Differences Between Vue and React
2 Way vs 1 Way Data Flow
React has a 1 way data flow. Component state is updated using setState or with a useState hook. You can also pass data to child components using props.
const [data, updateData] = useState({ firstName: "John", lastName: "Doe" });
updateData({ firstName: "Bob", ...data });
Changing a component's state in React takes a little more effort but it does make updates easier to understand.
Vue components handle state using a data function. Its just a function that returns an object. A Vue component's state can be updated in a few different ways.
A component method can change state. You don't need to call a special function. Just a simple assignment can update component state.
data() {
return {
firstName: "John",
lastName: "Doe",
}
},
methods: {
update() {
this.firstName = "Bob";
}
}
State can also be updated using v-model documentation. v-model binds data for form inputs to create 2-way data binding.
<input type="text" v-model="firstName" />
Typing a value into the firstName input will update component state. This is one of my favorite Vue features because it makes it so easy to build forms. But it can make it more difficult to understand where state is changing.
Forms in React generally require a handleChange function that gets called whenever the form input value is updated.
Component Structure
React components are written entirely in JavaScript. React components can contain a template (HTML), behavior (JavaScript), and styles (CSS in JS). However the entire component is JavaScript. During the build process it gets converted to HTML, JavaScript, and CSS.
Vue Single File Components (SFCs) can contain HTML, CSS, and JavaScript. Vue components usually have 3 blocks. The template, script, and style blocks.
The Vue Options API also provides more structure to a SFC script block. The SFC exports a JavaScript object with a data method, lifecycle hook methods, a methods, props, computed, and watch properties. Its very easy to follow and know where to place new code.
React components don't have the same structure but can still contain all of the same functionality. Just with a looser structure.
Functional Components
While Vue has functional/render components, they aren't as nice as React's stateless functional components. But I have not run into any situations where I needed to use render components.
Component Styling
React components cannot contain Vanilla CSS. As discussed above, Vue SFCs have style blocks that can contain CSS.
There are a few options for styling React components. Traditional CSS files, inline CSS, Styled Components, and CSS modules. I don't recommend inline CSS for all of your styling. I have used traditional CSS file and CSS modules to style React components. Right now I'm using CSS modules. They are easy to set up and offer style scoping that's similar to Vue SFCs.
Parent/Child Communication
Both React and Vue use props to pass data from the parent to child components.
Vue uses custom emitted events to pass data from child components to the parent. In React data gets passed up to the parent through functions.
Directives
One of my favorite features of Vue is its directives. These are special attributes you can add to your template HTML. These directives add logic to your template without adding a ton of code. The most used are v-for, v-bind, v-on, and v-if/v-else-if/v-else. v-model is also a directive.
Here's an example.
<ul v-if="hasItems">
<li v-for="item in items" v-bind:key="item.id">
<button v-on:click="addItem(item)">{{item.name}}</button>
</li>
</ul>
<p v-else>No Items</p>
Here's the same functionality in React with JSX.
hasItems ? (
<ul>
{items.map((item) => (
<li key={item.id}>
<button onClick={() => addItem(item)}>{item.name}</button>
</li>
))}
</ul>
) : (
<p>No Items</p>
);
The Vue template code is much cleaner and way more similar to regular HTML. It also reads clearly when compared to the React JSX. However the JSX is just plain JavaScript with some HTML markup. Its also easy to understand if you're used to writing JavaScript.
One common complaint I hear about Vue directives is that its just a lot more to learn. But there aren't many commonly used directives and they're pretty intuitively named. After you build a few components you'll probably have them memorized.
Slots and Children
Vue and React each have ways to create wrapper components. React uses a "children" prop. Vue uses slots.
React can also take components as props.
Transitions and Animations
Vue includes transitions out of the box. There are a few libraries for adding transitions and animations in React like React Spring and React Motion but you have to add them yourself.
So Which Do I Like Better?
I've used both in production and I was able to contribute to an existing project almost immediately. Vue is a little easier to pick up if you don't have a strong JavaScript background. But if you love writing JavaScript you'll like Vue.
I didn't really like React class based components but a few years back we got React hooks. The useState example above is an example of a React hook. These make updating state so much easier. They can also do so much more than handling state. This site has a ton of examples. Vue 3 added the Composition API which works a lot like React hooks.
As we discussed above, build forms in Vue is so much easier. Building React forms can be very tedious but a lot of the code can be abstracted. There are also some libraries like Formick that can help.
Vue directives enable you to write much cleaner templates but JSX is really powerful. It just comes down to you and your team's preference.
The Vue and React teams seem to be learning from one another and both frameworks are getting some awesome features. Honestly I don't think you can go wrong with either. If you can only learn one learn React. It has a wider user base since so many companies use it. But if you have time learn both.