Table of Contents
- Prerequisites
- Setting Up Your Development Environment
- Creating Your First Vue Project
- Understanding the Project Structure
- Building the To-Do App: Core Functionality
- Adding Interactivity with Vue Directives
- Styling Your App
- Testing the App
- Deploying Your App
- Conclusion
Prerequisites
Before diving in, ensure you have the following tools installed:
-
Node.js & npm: Vue requires Node.js (v14.0.0+ recommended) and npm (v6.0.0+). Download them from nodejs.org. Verify installation with:
node -v # Should return a version like v18.17.0 npm -v # Should return a version like 9.6.7 -
Code Editor: Use VS Code (recommended) with the Volar extension for Vue 3 support (replaces the older Vetur).
-
Basic Knowledge: Familiarity with HTML, CSS, and JavaScript (ES6+) will help, but we’ll explain key concepts as we go.
Setting Up Your Development Environment
Vue provides two main tools for project setup: Vue CLI (traditional, config-based) and Vite (modern, fast). We’ll use Vue CLI for this guide, as it’s more beginner-friendly for first projects.
Step 1: Install Vue CLI
Open your terminal and run:
npm install -g @vue/cli
Verify installation with:
vue --version # Should return a version like 5.0.8
Creating Your First Vue Project
Step 1: Generate a New Project
Run the following command and follow the prompts:
vue create my-first-vue-app
- Select a preset: Choose “Default (Vue 3)” (recommended for new projects).
- Wait for installation: Vue CLI will download dependencies and set up your project.
Step 2: Navigate to the Project Folder
cd my-first-vue-app
Step 3: Run the Development Server
Start the app locally with:
npm run serve
You’ll see output like:
App running at:
- Local: http://localhost:8080/
- Network: http://192.168.1.100:8080/
Open http://localhost:8080 in your browser—you’ll see the default Vue welcome page!
Understanding the Project Structure
Let’s explore the key files and folders in my-first-vue-app:
my-first-vue-app/
├── node_modules/ # Dependencies (auto-generated)
├── public/ # Static assets (e.g., index.html, favicon)
├── src/ # Source code (where you’ll work)
│ ├── assets/ # Images, fonts, etc.
│ ├── components/ # Reusable Vue components
│ ├── App.vue # Root component
│ └── main.js # Entry point (mounts the app)
├── .gitignore # Files to ignore in Git
├── package.json # Project metadata and scripts
└── README.md # Project documentation
src/App.vue: The root component of your app. Vue uses Single-File Components (SFCs), which bundle HTML (template), JavaScript (script), and CSS (style) in one file.src/main.js: Initializes Vue and mountsApp.vueto the DOM (checkpublic/index.htmlfor the<div id="app">where it mounts).
Building the To-Do App: Core Functionality
We’ll build a simple to-do list app with:
- A text input to add new todos.
- A list to display todos.
- Buttons to delete todos.
- Checkboxes to mark todos as “completed.”
Step 1: Clean Up the Default App
Open src/App.vue and replace its contents with:
<template>
<div class="app">
<h1>My Vue To-Do List</h1>
<!-- We’ll add our to-do form and list here -->
</div>
</template>
<script>
export default {
name: 'App',
// Data, methods, and logic will go here
}
</script>
<style>
/* CSS styles will go here */
</style>
Step 2: Add the To-Do Form
In the <template> section, add a form with an input and “Add” button:
<template>
<div class="app">
<h1>My Vue To-Do List</h1>
<!-- Add Todo Form -->
<form @submit.prevent="addTodo">
<input
type="text"
v-model="newTodo"
placeholder="Enter a new todo..."
required
>
<button type="submit">Add</button>
</form>
<!-- Todo List -->
<ul class="todo-list">
<!-- We’ll loop through todos here -->
</ul>
</div>
</template>
@submit.prevent: Prevents the default form submission (reloading the page) and calls theaddTodomethod.v-model="newTodo": Two-way data binding—links the input value to anewTodovariable in your component.
Step 3: Define Data and Methods
In the <script> section, add data (reactive state) and methods (functions):
<script>
export default {
name: 'App',
data() {
return {
newTodo: '', // Tracks the input value
todos: [ // Array to store todos
// Example initial todo
{ id: 1, text: 'Learn Vue.js', completed: false }
]
};
},
methods: {
addTodo() {
// Only add if input isn’t empty
if (this.newTodo.trim()) {
this.todos.push({
id: Date.now(), // Unique ID using timestamp
text: this.newTodo,
completed: false
});
this.newTodo = ''; // Clear input after adding
}
},
deleteTodo(todoId) {
this.todos = this.todos.filter(todo => todo.id !== todoId);
}
}
};
</script>
Step 4: Display the Todo List
Update the <template> to loop through todos with v-for:
<!-- Todo List -->
<ul class="todo-list">
<li v-for="todo in todos" :key="todo.id" class="todo-item">
<input
type="checkbox"
v-model="todo.completed"
>
<span :class="{ completed: todo.completed }">{{ todo.text }}</span>
<button @click="deleteTodo(todo.id)">×</button>
</li>
</ul>
v-for="todo in todos": Loops through thetodosarray and renders a<li>for each todo.:key="todo.id": Required for Vue to track list items (use a unique ID).v-model="todo.completed": Binds the checkbox to thecompletedboolean in the todo object.:class="{ completed: todo.completed }": Applies thecompletedCSS class iftodo.completedis true.
Adding Interactivity
Let’s break down the key Vue directives used:
v-model: Two-way data binding. Syncs form inputs with component data (e.g.,newTodoand the text input,todo.completedand the checkbox).v-for: Renders a list from an array (loop throughtodos).@click(shorthand forv-on:click): Listens for click events (e.g.,deleteTodowhen the ”×” button is clicked).:class(shorthand forv-bind:class): Conditionally applies CSS classes (e.g.,completedclass for done todos).
Styling Your App
Add CSS to the <style> section (use scoped to limit styles to this component):
<style scoped>
.app {
max-width: 600px;
margin: 2rem auto;
padding: 0 1rem;
font-family: Arial, sans-serif;
}
form {
margin-bottom: 2rem;
display: flex;
gap: 0.5rem;
}
input[type="text"] {
flex: 1;
padding: 0.5rem;
font-size: 1rem;
}
button {
padding: 0.5rem 1rem;
background: #42b983; /* Vue’s brand color */
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background: #359469;
}
.todo-list {
list-style: none;
padding: 0;
}
.todo-item {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.5rem;
margin-bottom: 0.5rem;
background: #f5f5f5;
border-radius: 4px;
}
.todo-item .completed {
text-decoration: line-through;
color: #888;
}
.todo-item button {
margin-left: auto;
background: #ff4444;
padding: 0.25rem 0.5rem;
}
.todo-item button:hover {
background: #cc0000;
}
</style>
Testing the App
Run npm run serve (if not already running) and open http://localhost:8080. Test:
- Add a todo: Type text and click “Add” (empty inputs are ignored).
- Mark as completed: Check the checkbox (text gets a line-through).
- Delete a todo: Click the ”×” button.
Deploying Your App
To share your app, build a production-ready version:
Step 1: Build the Project
Run:
npm run build
This generates a dist/ folder with optimized HTML, CSS, and JS files.
Step 2: Deploy the dist/ Folder
Options for deployment:
- Netlify/Vercel: Drag-and-drop the
dist/folder to their dashboards. - GitHub Pages: Push the
dist/folder to agh-pagesbranch (usevue-cli-plugin-gh-pagesfor automation). - Firebase Hosting: Use
firebase deployafter setting up Firebase CLI.
Conclusion
You’ve built your first Vue.js app! You learned:
- How to set up a Vue project with Vue CLI.
- Core Vue concepts: SFCs, reactivity (
data), directives (v-model,v-for,v-on), and methods. - How to add interactivity and style components.
Next steps: Explore Vue Router (for multi-page apps), Pinia (state management), or dive deeper into the Vue Docs.