If you've never touched Vue.js before, this guide is for you. No assumptions, no jargon left unexplained. By the end, you'll have a working Vue app and understand why every line of code is there.
1. What even is Vue.js?
Vue is a JavaScript framework for building interactive websites. Normally, if you want a webpage to update itself (like a counter that goes up when you click a button), you write a bunch of manual code to find the element, change its text, and keep everything in sync.
Vue does that syncing for you. You just say "this number is 5" and "show this number on the page," and whenever the number changes, Vue updates the page automatically. This idea is called reactivity.
Think of it like a spreadsheet. If cell B1 says =A1 + 1, and you change A1, B1 updates itself — you don't manually retype it. Vue does the same thing for your webpage.
2. The absolute simplest Vue app (no installation needed)
You don't need to install anything to try Vue. You can just create an HTML file and load Vue from the internet.
Create a file called index.html and paste this in:
<!DOCTYPE html>
<html>
<head>
<title>My First Vue App</title>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
<div id="app">
<h1>{{ message }}</h1>
<button @click="count++">Clicked {{ count }} times</button>
</div>
<script>
const { createApp } = Vue
createApp({
data() {
return {
message: 'Hello, Vue!',
count: 0
}
}
}).mount('#app')
</script>
</body>
</html>
Open that file in your browser (just double-click it). You'll see "Hello, Vue!" and a button that counts up every time you click it.
Let's break down what just happened
<div id="app">— This is the "zone" Vue is allowed to control. Anything inside it, Vue can manage. Anything outside it, Vue ignores.{{ message }}— Double curly braces are how you display a piece of data on the page. Vue swaps it out for the real value.data()— This is where you define the pieces of information ("state") your app cares about, likemessageandcount.@click="count++"— The@clickpart means "when this is clicked, run this code." So every click just increasescountby 1.createApp({...}).mount('#app')— This creates the Vue app and tells it "attach yourself to the element with idapp."
That's it. That's a real, working Vue app. Everything else you learn about Vue builds on this same idea: data goes in, Vue keeps the page updated automatically.
3. Showing and hiding things
Let's make our app a little more interesting — a message that appears and disappears.
<div id="app">
<button @click="showMessage = !showMessage">Toggle Message</button>
<p v-if="showMessage">👋 Peekaboo! You found me.</p>
</div>
<script>
const { createApp } = Vue
createApp({
data() {
return {
showMessage: true
}
}
}).mount('#app')
</script>
v-if="showMessage"— Only show this element ifshowMessageistrue.showMessage = !showMessage— Flipstruetofalseand back again (that's what the!does — it means "not").
Try it: click the button and watch the message appear and disappear.
4. Making a list (like a to-do list)
Most real apps show lists of things: products, messages, tasks. Vue makes this easy with v-for.
<div id="app">
<ul>
<li v-for="fruit in fruits">{{ fruit }}</li>
</ul>
</div>
<script>
const { createApp } = Vue
createApp({
data() {
return {
fruits: ['Apple', 'Banana', 'Cherry']
}
}
}).mount('#app')
</script>
v-for="fruit in fruits" reads as: "for each item in the fruits list, call it fruit, and repeat this element once per item." Vue automatically creates one <li> per fruit.
Let's build a real, working to-do list
<div id="app">
<input v-model="newTask" placeholder="Add a task...">
<button @click="addTask">Add</button>
<ul>
<li v-for="(task, index) in tasks">
{{ task }}
<button @click="removeTask(index)">❌</button>
</li>
</ul>
</div>
<script>
const { createApp } = Vue
createApp({
data() {
return {
newTask: '',
tasks: ['Learn Vue', 'Build an app']
}
},
methods: {
addTask() {
if (this.newTask.trim() === '') return
this.tasks.push(this.newTask)
this.newTask = ''
},
removeTask(index) {
this.tasks.splice(index, 1)
}
}
}).mount('#app')
</script>
New concepts here:
v-model="newTask"— This links an input box directly to a piece of data. Whatever the user types automatically becomes the value ofnewTask. No manual "read what's in the box" code needed.methods— This is where you define functions your app can run, usually triggered by clicks. Think ofdataas "the nouns" (information) andmethodsas "the verbs" (actions).this.tasks.push(...)— Adds a new item to the list. Becausetasksis reactive data, the page updates itself instantly.this.tasks.splice(index, 1)— Removes one item at a specific position in the list.
At this point, you have a genuinely functional to-do app in about 25 lines of code.
5. Organizing your app with "components"
Once your app grows, you don't want everything crammed into one file. Vue lets you split your UI into reusable building blocks called components — think of them like custom, reusable HTML tags you design yourself.
<div id="app">
<task-item text="Learn Vue"></task-item>
<task-item text="Build an app"></task-item>
<task-item text="Show it off"></task-item>
</div>
<script>
const { createApp } = Vue
const app = createApp({})
app.component('task-item', {
props: ['text'],
template: `<p>✅ {{ text }}</p>`
})
app.mount('#app')
</script>
app.component('task-item', {...})— This defines a new, reusable piece calledtask-item.props: ['text']— This says "this component accepts a piece of data calledtextfrom whoever uses it."<task-item text="Learn Vue">— This is how you "use" the component, passing in thetextprop like an HTML attribute.
Components are the foundation of how real Vue apps are built — buttons, cards, headers, forms, all as small, reusable pieces you can mix and match.
6. Ready for a real project? Use the Vue CLI
Everything so far worked in a single HTML file, which is great for learning. But real apps use a proper project setup with tools that catch your mistakes, bundle your files efficiently, and let you write .vue files (a special format that keeps HTML, JavaScript, and CSS for one component together).
To create a real project, you need Node.js installed. Then run this in your terminal:
npm create vue@latest
You'll be asked a few yes/no questions (project name, whether you want TypeScript, testing, etc.) — for your first project, it's fine to answer "No" to everything except the project name.
Then:
cd your-project-name
npm install
npm run dev
This starts a local server (usually at http://localhost:5173) where you can see your app live, and it auto-refreshes every time you save a file.
What a .vue file looks like
In a real project, each component lives in its own .vue file, structured like this:
<template>
<div>
<h1>{{ greeting }}</h1>
<button @click="changeGreeting">Change greeting</button>
</div>
</template>
<script>
export default {
data() {
return {
greeting: 'Hello!'
}
},
methods: {
changeGreeting() {
this.greeting = 'You changed me!'
}
}
}
</script>
<style>
h1 {
color: teal;
}
</style>
Notice it's the exact same ideas as before (data, methods, {{ }}, @click) — just organized into three clear sections: what it looks like (template), how it behaves (script), and how it's styled (style).
7. Quick cheat sheet
| Syntax | What it does |
|---|---|
{{ value }} |
Display a piece of data on the page |
v-if="condition" |
Show an element only if the condition is true |
v-for="item in list" |
Repeat an element for each item in a list |
@click="doSomething" |
Run code when the element is clicked |
v-model="value" |
Two-way link between an input and a piece of data |
data() |
Where you define your app's information |
methods |
Where you define your app's actions |
props |
Data passed into a component from its parent |
8. Where to go next
- Try modifying the to-do list example above — add a "mark as done" button.
- Learn about
computedproperties (values that automatically recalculate based on other data). - Explore the official Vue docs at vuejs.org — they're beginner-friendly and full of interactive examples.
The core idea to hold onto: you describe what your data looks like, and what the page should show based on that data — and Vue handles keeping the two in sync. Everything else in Vue is just more ways to apply that one idea.