Vue.js Beginner to Advanced 2025: Complete Guide
Last Updated on Jul 21, 2025
- Introduction
- What Is Vue.js?
- Why Choose Vue.js in 2025?
- How to Install Vue.js
- Core Concepts for Beginners
- Intermediate Concepts
- Advanced Concepts
- Best Practices
- Mini Project: Build a Vue 3 Task Tracker
- Step 1: Set Up the Project
- Step 2: Project Structure
- Step 3: Define the Task Store with Pinia
- Step 4: Add Routing
- Step 5: Build the Components
- Step 6: Create the Home Page
- Step 7: Create the About Page
- Step 8: Create the App Layout
- Final Result
- Encourage Experimentation
- Common Pitfalls
- Conclusion
- Key Takeaways
Introduction
Vue.js has evolved into one of the most popular JavaScript frameworks for building dynamic web applications. As of 2025, it continues to strike a balance between simplicity and capability, offering a progressive approach to front-end development. Whether you’re just starting out or looking to refine your skills, understanding how Vue.js works—from core concepts to advanced patterns—is essential.
In this comprehensive guide, we’ll take you from Vue.js basics all the way to advanced techniques, focusing on the latest version (Vue 3.x and its ecosystem). This pillar post will help you understand how to get started, structure your projects, and leverage Vue.js’s full power.
What Is Vue.js?
Vue.js is an open-source JavaScript framework for building user interfaces and single-page applications (SPAs). It’s known for its approachable learning curve, reactive data-binding system, and component-based architecture.
Key Characteristics:
- Progressive Framework: Use as much or as little as you need.
- Declarative Rendering: Ties the UI to the underlying data model.
- Component-Based: Build complex UIs using small, reusable components.
- Virtual DOM: Optimizes performance by minimizing direct DOM manipulation.
Why Choose Vue.js in 2025?
- Mature Ecosystem: Vite, Vue Router, and Pinia for state management.
- TypeScript Support: First-class TypeScript support built-in.
- Performance: Lightweight, fast-loading applications.
- Strong Community and Documentation: Extensive resources and support channels.
- Versatility: Suitable for both small-scale and large-scale enterprise applications.
How to Install Vue.js
There are several ways to start using Vue.js. For beginners, using Vite is now the recommended method. Vue CLI is largely considered legacy as of 2025.
Installation Steps
-
Install Node.js: Make sure you have Node.js installed. You can check by running:
node -v npm -vDownload from: https://nodejs.org/
-
Create a New Vue Project Using Vite:
npm create vite@latest my-vue-app -- --template vue cd my-vue-app npm install npm run dev -
Open Your App: Visit
http://localhost:5173in your browser.
This creates a fully scaffolded Vue 3 project using Vite, with hot module replacement and other modern build features.
Core Concepts for Beginners
1. The Vue Instance
At the heart of every Vue app is a Vue instance. When using Vue 3 with modules, you’ll commonly see:
import { createApp } from 'vue';
const app = createApp({
data() {
return {
message: "Hello Vue!"
};
}
});
app.mount("#app");
- data(): Returns reactive properties.
- methods: Functions tied to instance data.
- mount(): Ties Vue to a DOM element.
Note: In Vue 3,
Vue.createAppreplaces the old Vue constructor from Vue 2.
2. Template Syntax
Vue uses an HTML-based template syntax that lets you declaratively bind data to the rendered DOM.
-
Text Interpolation:
{{ message }} -
Directives: Vue provides built-in directives like
v-if,v-for, andv-bind.<p v-if="visible">This is visible</p>
Explanation: Directives are special tokens in the markup that tell Vue to do something to a DOM element.
3. Components
Components are reusable Vue instances with a name.
Example:
app.component("my-button", {
template: `<button>Click Me</button>`
});
- Props: Pass data from parent to child components.
- Slots: Insert content into child components.
- Emits: Send events from child to parent.
Clarification: Each component must be registered before use when using the Options API. With Single File Components (SFCs), components are imported and declared in the
componentsobject or using<script setup>.
4. Reactivity System
Vue’s reactivity allows the DOM to automatically update when the underlying state changes.
-
Reactive Refs:
import { ref } from 'vue'; const count = ref(0); -
Computed Properties:
import { computed } from 'vue'; const doubleCount = computed(() => count.value * 2);
Explanation:
ref()is used for primitive types like numbers and strings.reactive()is used for objects and arrays.computed()creates derived values that automatically update when dependencies change.
Intermediate Concepts
5. Vite as the Default Build Tool
Vue CLI is mostly phased out in favor of Vite.
Why Vite?
- Faster startup and hot reload times.
- Native ES Modules support.
Getting Started with Vite:
As outlined in the Installation section above.
6. Vue Router
Used for navigating between pages in SPAs.
Installation:
npm install vue-router
Basic Setup:
import { createRouter, createWebHistory } from 'vue-router';
const routes = [
{ path: '/', component: Home },
{ path: '/about', component: About }
];
const router = createRouter({
history: createWebHistory(),
routes
});
app.use(router);
Explanation:
createWebHistory()uses the browser’s History API for clean URLs.- Always register the router using
app.use(router)in your main.js or main.ts.
7. State Management with Pinia
Pinia replaces Vuex as the official state management library for Vue 3.
Installation:
npm install pinia
Creating a Store:
import { defineStore } from 'pinia';
export const useCounterStore = defineStore('counter', {
state: () => ({ count: 0 }),
actions: {
increment() {
this.count++;
}
}
});
Setting Up Pinia:
Make sure to add Pinia to your Vue app:
import { createPinia } from 'pinia';
app.use(createPinia());
Advanced Concepts
8. Composition API
The Composition API is a set of additive, function-based APIs that allow for better logic reuse and organization.
Example:
import { ref } from 'vue';
export default {
setup() {
const count = ref(0);
const increment = () => count.value++;
return { count, increment };
}
}
Explanation:
setup()is the entry point for Composition API logic in a component.- Return values from
setup()become available in the template.
9. TypeScript with Vue
Vue 3 offers first-class TypeScript support.
Basic Component:
<script lang="ts" setup>
import { ref } from 'vue';
const count = ref<number>(0);
</script>
- Type Inference: Improves development efficiency.
- Typed Props/Emits: Define expected types for properties and events.
Example of Typed Props:
<script lang="ts" setup>
defineProps<{ title: string }>();
</script>
10. Server-Side Rendering (SSR)
Vue supports SSR for SEO-friendly applications and faster initial page loads using Nuxt.js or Vue’s native SSR setup.
Nuxt 3 (Recommended for SSR):
- Built on Vue 3 and Vite.
- Simplifies complex server-side rendering configurations.
Best Practices
- Use the Composition API for better scalability.
- Structure projects by feature, not file type.
- Keep components small and focused.
- Leverage Vite for development performance.
- Integrate automated testing (e.g., Vitest, Cypress).
- Optimize for accessibility and performance using Vue DevTools.
- Always clean up side effects in lifecycle hooks.
Mini Project: Build a Vue 3 Task Tracker
Now that you’ve explored Vue’s core and advanced concepts, let’s bring it all together by building a simple Task Tracker. This app will allow users to:
- Add tasks
- Mark tasks as complete
- Delete tasks
- View a filtered list (All / Completed / Pending)
- Navigate between “Home” and “About” pages
We'll use Vue 3, Pinia for state management, and Vue Router for navigation.
Step 1: Set Up the Project
Make sure you’ve followed the installation steps using Vite:
npm create vite@latest vue-task-tracker -- --template vue
cd vue-task-tracker
npm install
npm install pinia vue-router
npm run dev
Step 2: Project Structure
Inside src/, create these folders and files:
src/
├── components/
│ ├── TaskInput.vue
│ └── TaskItem.vue
├── pages/
│ ├── Home.vue
│ └── About.vue
├── store/
│ └── taskStore.ts
├── router.ts
├── App.vue
└── main.ts
Step 3: Define the Task Store with Pinia
src/store/taskStore.ts
import { defineStore } from 'pinia';
export const useTaskStore = defineStore('task', {
state: () => ({
tasks: [
{ id: 1, text: 'Learn Vue 3', done: false },
{ id: 2, text: 'Build a project', done: true },
],
filter: 'all' // all | done | pending
}),
actions: {
addTask(text: string) {
this.tasks.push({
id: Date.now(),
text,
done: false
});
},
removeTask(id: number) {
this.tasks = this.tasks.filter(task => task.id !== id);
},
toggleDone(id: number) {
const task = this.tasks.find(t => t.id === id);
if (task) task.done = !task.done;
},
setFilter(value: string) {
this.filter = value;
}
},
getters: {
filteredTasks(state) {
if (state.filter === 'done') return state.tasks.filter(t => t.done);
if (state.filter === 'pending') return state.tasks.filter(t => !t.done);
return state.tasks;
}
}
});
Step 4: Add Routing
src/router.ts
import { createRouter, createWebHistory } from 'vue-router';
import Home from './pages/Home.vue';
import About from './pages/About.vue';
export const router = createRouter({
history: createWebHistory(),
routes: [
{ path: '/', component: Home },
{ path: '/about', component: About }
]
});
Update main.ts to use both Pinia and Router:
import { createApp } from 'vue';
import App from './App.vue';
import { createPinia } from 'pinia';
import { router } from './router';
const app = createApp(App);
app.use(createPinia());
app.use(router);
app.mount('#app');
Step 5: Build the Components
TaskInput.vue
<template>
<div>
<input v-model="newTask" @keyup.enter="submitTask" placeholder="Add a new task" />
<button @click="submitTask">Add</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { useTaskStore } from '../store/taskStore';
const store = useTaskStore();
const newTask = ref('');
function submitTask() {
if (newTask.value.trim()) {
store.addTask(newTask.value.trim());
newTask.value = '';
}
}
</script>
TaskItem.vue
<template>
<div :class="{ done: task.done }">
<input type="checkbox" :checked="task.done" @change="toggle" />
{{ task.text }}
<button @click="remove">x</button>
</div>
</template>
<script setup>
defineProps(['task']);
import { useTaskStore } from '../store/taskStore';
const store = useTaskStore();
function toggle() {
store.toggleDone(task.id);
}
function remove() {
store.removeTask(task.id);
}
</script>
<style scoped>
.done {
text-decoration: line-through;
}
</style>
Step 6: Create the Home Page
Home.vue
<template>
<div>
<h1>Task Tracker</h1>
<TaskInput />
<div>
<button @click="store.setFilter('all')">All</button>
<button @click="store.setFilter('done')">Done</button>
<button @click="store.setFilter('pending')">Pending</button>
</div>
<div v-for="task in store.filteredTasks" :key="task.id">
<TaskItem :task="task" />
</div>
</div>
</template>
<script setup>
import TaskInput from '../components/TaskInput.vue';
import TaskItem from '../components/TaskItem.vue';
import { useTaskStore } from '../store/taskStore';
const store = useTaskStore();
</script>
Step 7: Create the About Page
About.vue
<template>
<div>
<h1>About This App</h1>
<p>This is a simple Vue 3 project to practice components, state management, and routing.</p>
</div>
</template>
Step 8: Create the App Layout
Update App.vue to include navigation:
<template>
<nav>
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</nav>
<router-view />
</template>
<style>
nav {
margin-bottom: 1rem;
}
</style>
Final Result
By the end of this mini project, your readers will have used:
- Reactive state via
refandcomputed - Component communication (props and events)
- Pinia for centralized state management
- Vue Router for page navigation
- Composition API for setup logic
Encourage Experimentation
Want more practice? Try adding:
- Task editing functionality
- Save tasks to localStorage
- Add a completed task counter
- Style it with Tailwind CSS or custom CSS
Common Pitfalls
- Overusing global state instead of local component state.
- Ignoring TypeScript benefits.
- Not setting up routing guards for secure apps.
- Forgetting to clean up side effects like intervals or subscriptions.
- Mixing Options API and Composition API unnecessarily.
Conclusion
Vue.js in 2025 remains a top choice for developers building web apps of all sizes. With modern tools like Vite, Pinia, and TypeScript integration, Vue offers flexibility and scalability that meet both beginner and advanced needs.
By understanding Vue’s core concepts, exploring intermediate tools, and mastering advanced patterns, you’ll be able to build high-quality, maintainable applications that stand the test of time.
Key Takeaways
- Vue.js is a progressive JavaScript framework that’s approachable yet powerful.
- Components, reactive data, and directives form the core building blocks.
- Vite is now the go-to build tool for Vue applications.
- Vue Router and Pinia provide routing and state management essentials.
- The Composition API and TypeScript offer scalability and maintainability.
- Best practices include modular architecture, testing, and performance optimization.