Vue.js 3 Tutorial: Why Some Developers Prefer It Over React
Vue.js 3 tutorial for beginners: Composition API, reactivity, components, and why many developers choose Vue over React for frontend development.
Get more content like this on Telegram!
Daily AI tips, notes & resources ā free
Vue.js 3 Tutorial: Why Some Developers Prefer It Over React
When I mentioned to a colleague that I was learning Vue, she said: "But why would you bother when React exists?"
I had the same question. Then I spent two weeks with Vue 3 and Nuxt.js, and I understood why a significant slice of the frontend community swears by it.
Vue isn't better than React. React isn't better than Vue. They make different design decisions, and for some people and some projects, Vue's decisions feel more natural. Understanding what those decisions are is worth your time as a developer.
This tutorial teaches Vue 3 fundamentals by building real UI components. It assumes you know basic JavaScript and have seen some React.
What Makes Vue Different
Vue 3's Single File Components (SFCs) keep template, logic, and styles in one .vue file:
<!-- Everything about this component in one file -->
<template>
<div class="counter">
<p>Count: {{ count }}</p>
<button @click="increment">+</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
const count = ref(0);
const increment = () => count.value++;
</script>
<style scoped>
.counter {
display: flex;
align-items: center;
gap: 1rem;
}
</style>
The SFC format is what many developers love about Vue ā everything related to a component is in one file, logically separated but visually connected. React keeps template (JSX) and logic together but separates CSS. Vue separates all three concerns while colocating them.
Setup
npm create vue@latest my-vue-app
cd my-vue-app
npm install
npm run dev
Select: TypeScript (recommended), Vue Router, Pinia (state management).
Core Concept 1: Reactivity
Vue's reactivity system is how it tracks data changes and updates the DOM.
<script setup>
import { ref, reactive, computed } from 'vue';
// ref ā for primitive values
const name = ref('Alice');
const age = ref(30);
// Access with .value in JavaScript
console.log(name.value); // 'Alice'
name.value = 'Bob';
// reactive ā for objects (no .value needed)
const user = reactive({
name: 'Alice',
email: 'alice@example.com',
role: 'admin',
});
// Modify directly ā Vue tracks it
user.name = 'Bob';
// computed ā derived reactive values
const greeting = computed(() => `Hello, ${user.name}!`);
</script>
<template>
<!-- In templates, .value is automatic ā no need to write it -->
<p>{{ name }}</p>
<p>{{ user.email }}</p>
<p>{{ greeting }}</p>
</template>
Core Concept 2: Template Directives
Vue uses directives ā special attributes prefixed with v- ā to add dynamic behavior to templates:
<template>
<!-- v-if / v-else ā conditional rendering -->
<div v-if="isLoggedIn">Welcome back!</div>
<div v-else>Please log in</div>
<!-- v-for ā list rendering -->
<ul>
<li v-for="item in items" :key="item.id">
{{ item.name }}
</li>
</ul>
<!-- v-bind (shorthand :) ā dynamic attributes -->
<img :src="imageUrl" :alt="imageDescription" />
<!-- v-on (shorthand @) ā event listeners -->
<button @click="handleClick">Click me</button>
<input @keyup.enter="handleEnter" />
<!-- v-model ā two-way binding for form inputs -->
<input v-model="searchQuery" placeholder="Search..." />
<p>Searching for: {{ searchQuery }}</p>
</template>
<script setup>
import { ref } from 'vue';
const isLoggedIn = ref(true);
const items = ref([{ id: 1, name: 'Item 1' }, { id: 2, name: 'Item 2' }]);
const searchQuery = ref('');
</script>
v-model is one of Vue's most loved features ā two-way binding on form inputs with zero ceremony. In React, you need a controlled input with value and onChange.
Core Concept 3: Components and Props
<!-- components/TaskItem.vue -->
<template>
<div
class="task-item"
:class="{ done: task.done }"
@click="$emit('toggle', task.id)"
>
<input type="checkbox" :checked="task.done" @change="$emit('toggle', task.id)" />
<span>{{ task.text }}</span>
<button @click.stop="$emit('delete', task.id)">Ć</button>
</div>
</template>
<script setup lang="ts">
interface Task {
id: number;
text: string;
done: boolean;
}
defineProps<{
task: Task;
}>();
defineEmits<{
toggle: [id: number];
delete: [id: number];
}>();
</script>
<!-- App.vue ā using the component -->
<template>
<div>
<TaskItem
v-for="task in tasks"
:key="task.id"
:task="task"
@toggle="toggleTask"
@delete="deleteTask"
/>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import TaskItem from './components/TaskItem.vue';
const tasks = ref([
{ id: 1, text: 'Learn Vue', done: false },
{ id: 2, text: 'Build something', done: false },
]);
const toggleTask = (id: number) => {
const task = tasks.value.find(t => t.id === id);
if (task) task.done = !task.done;
};
const deleteTask = (id: number) => {
tasks.value = tasks.value.filter(t => t.id !== id);
};
</script>
Core Concept 4: Lifecycle Hooks
<script setup>
import { onMounted, onUnmounted, onUpdated } from 'vue';
// Runs after component is mounted to DOM
onMounted(() => {
console.log('Component mounted');
window.addEventListener('resize', handleResize);
});
// Runs when component is removed from DOM
onUnmounted(() => {
window.removeEventListener('resize', handleResize);
});
// Runs after component updates
onUpdated(() => {
console.log('Component updated');
});
</script>
Vue 3 vs React: Honest Comparison
| Vue 3 | React | |
|---|---|---|
| Learning curve | Lower | Higher |
| Template syntax | HTML-like | JSX (JS-first) |
| Two-way binding | Built-in (v-model) | Manual (value + onChange) |
| State management | Pinia (official) | Zustand, Redux, Jotai |
| SSR framework | Nuxt.js | Next.js |
| Job market | Smaller | Much larger |
| TypeScript support | Excellent | Excellent |
| Ecosystem size | Large | Very large |
| Community | Growing | Dominant |
Why Some Developers Choose Vue
I surveyed Vue developers for their reasons. The most common:
-
Templates feel natural ā Vue's template syntax feels more like HTML. JSX feels more like JavaScript. Backend developers transitioning to frontend often find Vue more approachable.
-
v-model is delightful ā Two-way binding eliminates the controlled input ceremony.
-
Less "JavaScript all the way down" ā Vue's template separation feels cleaner to some developers.
-
Nuxt.js ā Vue's equivalent of Next.js is genuinely excellent and has caught up with Next.js in features.
-
Official state management ā Pinia is officially maintained. React's state story is fragmented (Redux, Zustand, Jotai, Context, Server State...).
When to Choose Vue vs React
Choose React if: you want the largest job market, the most libraries, and you're building React Native mobile apps.
Choose Vue if: you're coming from a backend background, working on a team that's comfortable with Vue, or you simply find the template syntax more natural.
For the React side of this comparison, our React tutorial for beginners walks through React fundamentals. To compare frameworks at a higher level, our React vs Next.js vs Remix guide covers the React ecosystem options. And for JavaScript fundamentals that apply to both Vue and React, our modern JavaScript 2025 guide is the foundation.
Frequently Asked Questions
Should I learn Vue.js or React first?
React has the larger job market. Vue is easier to start with. If employability is the goal, learn React. After one, the other is fast to pick up.
What is the Vue 3 Composition API?
The modern way to write Vue components using reactive functions (ref, reactive, computed) instead of the Options API. Similar to React hooks.
What is the difference between Vue 2 and Vue 3?
Vue 3 added the Composition API, better TypeScript, improved performance, and Fragments. Vue 3 is the current standard.
Is Vue.js good for large apps?
Yes, with Nuxt.js. GitLab, Alibaba, and others have large Vue codebases. Pinia + Vue Router + Nuxt form a complete ecosystem.
Frequently Asked Questions
AiTechWorlds Team
ā Verified WriterThe AiTechWorlds team is passionate about AI, technology, and education. We create high-quality, research-backed content to help you learn, grow, and succeed in the modern digital world.
Related Articles
How to Deploy a React App to Vercel in 10 Minutes
Deploy a React app to Vercel in 10 minutes: from npm create vite to live URL, custom domain setup, environment variables, and preview deployments.
GraphQL vs REST: Which API Style Should You Learn in 2025?
GraphQL vs REST API compared honestly for 2025: when each makes sense, real code examples, and which API style to learn first as a developer.
JavaScript Promises and Async/Await: Finally Understand Them
JavaScript async await and Promises explained clearly: the event loop, Promise chains, async/await patterns, error handling, and common mistakes to avoid.
How to Pass a JavaScript Interview at Google, Meta, or Amazon
How to pass a JavaScript interview at top tech companies: closures, event loop, promises, DOM questions, system design, and real interview questions answered.