This is a basic Vue.js example which explains how a basic Vue 3 application is built, interactively This example uses Vue 3 and Bootstrap 5, and uses HTML5 Local Storage to store the todos locally. It has less than 100 lines, but uses most of the main features of Vue.js.
Here is the Todo App in action:
The Todo App is made out of two files, the main HTML page, and the Vue component's code in JavaScript. The HTML file loads the JavaScript, and contains the HTML template which the Todo App component will use.
When writing Vue Single File Components, the component template is inside the same file as its code, but in this simplified example, it sits within the main HTML page.
Hover on the different sections of the source code to get an explanation for what each part does.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css">
<title>Vue Todo App</title>
</head>
<body>
<div id="app">
<div class="container">
<h1 class="my-3">Todo App</h1>
<form class="my-3" @submit.prevent="addTask">
<div class="row">
<div class="col-10">
<input class="form-control" v-model="newTodo"/>
</div>
<div class="col-2">
<button :disabled="newTodo.length === 0" class="btn btn-primary w-100">
Add
</button>
</div>
</div>
</form>
<ul class="list-group my-3">
<li
class="list-group-item d-flex justify-content-between align-items-center"
v-for="(todo, index) in todos"
>
<span>{{ todo }}</span>
<button class="btn btn-danger btn-sm" @click="deleteTask(index)">
<i class="bi bi-trash"></i>
</button>
</li>
</ul>
</div>
</div>
<script src="https://unpkg.com/vue@3"></script>
<script src="todo.js"></script>
</body>
</html>
const TodoApp = {
data() {
return {
todos: [],
newTodo: "",
}
},
mounted() {
const saved = localStorage.getItem("todos");
if (saved) {
this.todos = JSON.parse(saved);
}
},
methods: {
addTask() {
this.todos.push(this.newTodo);
this.newTodo = "";
},
deleteTask(index) {
this.todos.splice(index, 1);
}
},
watch: {
todos: {
handler() {
localStorage.setItem("todos", JSON.stringify(this.todos));
},
deep: true
}
}
}
const app = Vue.createApp(TodoApp);
const vm = app.mount('#app');