Bikin To-Do List Simpel dengan Vue JS: Panduan Praktis & Cepat
Hai gaes! Pernah gak sih ngerasa overwhelmed sama tumpukan tugas yang seabrek? Atau mungkin pengen banget bikin aplikasi sendiri tapi bingung mulai dari mana? Nah, pas banget! Kali ini kita bakal ngulik bareng gimana cara bikin aplikasi daftar tugas alias To-Do List yang simpel, fungsional, tapi tampilannya tetap kece, pake framework JavaScript kesayangan kita semua: Vue Js!
Siap-siap, karena setelah artikel ini, kamu auto bisa bikin To-Do List sendiri dan bisa pamer ke temen-temen kamu, ngab! Skuy!
Kenalan Dikit Sama Vue Js (Biar Makin Akrab, Gaes!)
Sebelum nyemplung ke kodenya, kita spill dikit yuk tentang Vue Js. Intinya, Vue itu framework JavaScript yang bikin develop UI (User Interface) jadi gampang banget, fleksibel, dan performanya sat-set. Cocok banget buat kamu yang pengen bikin aplikasi modern tanpa pusing tujuh keliling. Vibes-nya itu kayak ngobrol sama temen, friendly banget!
Konsep kunci yang bakal kita pake di To-Do List ini antara lain:
- Component: Anggap aja kayak main lego. Tiap bagian aplikasi (misal, input tugas, daftar tugas, tombol) itu komponen. Bikinnya terpisah, nanti tinggal digabung-gabung. Mantul!
- Reactivity: Ini nih magic-nya Vue! Tiap ada perubahan data, tampilan di UI langsung auto update tanpa kita suruh-suruh. Kece banget, kan?
- Data Binding (
v-model): Jembatan antara input form kamu sama data di JavaScript. Kamu ngetik di input, data di Vue langsung berubah. Data di Vue berubah, yang di input juga ikut berubah. Simpel! - List Rendering (
v-for): Kalo punya banyak data (kayak daftar tugas), Vue bisa nampilin datanya dalam bentuk daftar secara otomatis. Anti ribet bikin satu-satu. - Methods: Fungsi-fungsi yang kita bikin buat ngolah data atau ngerespons aksi pengguna (misal, nambah tugas, hapus tugas, tandai selesai).
Yuk, Gaspol! Bikin To-Do List-nya!
Kita akan bangun aplikasi ini step-by-step. Siapin kopi dan text editor favoritmu ya, ngab!
Step 1: Setup Proyek Vue (Pake Vite Biar Sat-Set!)
Pertama-tama, kita setup dulu proyek Vue-nya. Biar ngebut dan modern, kita pake Vite ya! Auto instan ini mah.
# Buka terminal/CMD kamu
npm create vue@latest my-todo-app
# Atau yarn create vue@latest my-todo-app
Nanti akan muncul beberapa pertanyaan, ikutin aja ya:
? Project name: my-todo-app(Tekan Enter)? Add TypeScript? No(Untuk tutorial ini kita pake JavaScript biar lebih simpel)? Add JSX Support? No? Add Vue Router for Single Page Application development? No? Add Pinia for State Management? No? Add Vitest for Unit Testing? No? Add Cypress for End-to-End testing? No? Add ESLint for code quality? No
Setelah itu, masuk ke folder proyek dan install dependency-nya:
cd my-todo-app
npm install
# Atau yarn install
Terakhir, jalanin proyeknya buat mastiin semuanya oke:
npm run dev
# Atau yarn dev
Mantul! Sekarang buka browser di http://localhost:5173 (atau port lain) dan kamu bakal liat boilerplate Vue-nya. Keren!
Step 2: Bersihin Proyek & Bikin Komponen TodoList.vue
Biar bersih vibes-nya, kita rapiin dikit App.vue yang jadi entry point utama aplikasi kita.
Hapus semua kode di App.vue, lalu buat file baru di src/components/TodoList.vue.
src/App.vue
<script setup>
import TodoList from './components/TodoList.vue'
</script>
<template>
<TodoList />
</template>
<style>
/* Styling dasar biar ga polosan */
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #f4f7f6;
display: flex;
justify-content: center;
align-items: flex-start; /* Mengubah align-items agar konten berada di atas */
min-height: 100vh;
margin: 0;
padding-top: 50px; /* Memberikan sedikit padding di atas */
box-sizing: border-box; /* Pastikan padding tidak menambah ukuran body */
}
</style>
Step 3: Struktur Dasar TodoList.vue
Sekarang kita mulai bikin struktur dasar di src/components/TodoList.vue. Kita akan pakai <script setup> yang bikin kodingan Vue jadi lebih ringkas dan modern.
src/components/TodoList.vue
<script setup>
import { ref, onMounted, watch } from 'vue';
// State aplikasi kita
const newTodo = ref(''); // Buat nyimpan teks tugas baru dari input
const todos = ref([]); // Array buat nyimpan semua daftar tugas
let nextId = 0; // Buat ID unik untuk setiap tugas
// --- METHODS AKAN DITAMBAHKAN DI SINI ---
const addTodo = () => {
// Fungsi untuk menambahkan tugas baru
if (newTodo.value.trim() !== '') { // Pastikan input tidak kosong
todos.value.push({
id: nextId++,
text: newTodo.value,
completed: false, // Defaultnya tugas belum selesai
});
newTodo.value = ''; // Kosongin input setelah ditambah
}
};
const toggleComplete = (id) => {
// Fungsi untuk menandai tugas selesai atau batal
const todo = todos.value.find(t => t.id === id);
if (todo) {
todo.completed = !todo.completed; // Balik status complete-nya
}
};
const removeTodo = (id) => {
// Fungsi untuk menghapus tugas
todos.value = todos.value.filter(t => t.id !== id);
};
// --- LIFE-CYCLE HOOKS UNTUK PERSISTENSI DATA ---
// onMounted: Jalan pas komponen selesai di-mount/muncul di DOM
onMounted(() => {
const savedTodos = localStorage.getItem('vue-todo-list');
if (savedTodos) {
todos.value = JSON.parse(savedTodos);
// Pastikan nextId juga di-update kalo ada data dari localStorage
// Ini penting agar ID tugas tidak duplikat setelah aplikasi di-reload
nextId = Math.max(...todos.value.map(todo => todo.id)) + 1;
if (nextId === -Infinity) nextId = 0; // Handle jika tidak ada todo sama sekali
}
});
// watch: Ngawasin perubahan di variabel 'todos', tiap ada perubahan, data disimpan ke localStorage
watch(todos, (newTodos) => {
localStorage.setItem('vue-todo-list', JSON.stringify(newTodos));
}, { deep: true }); // { deep: true } biar Vue ngecek perubahan di dalam objek tugas juga (misal status 'completed')
</script>
<template>
<div class="todo-app-container">
<h1>My Kece To-Do List</h1>
<div class="input-section">
<input
type="text"
v-model="newTodo"
@keyup.enter="addTodo"
placeholder="Tambahin tugas baru, yuk!"
class="todo-input"
/>
<button @click="addTodo" class="add-button">Tambah</button>
</div>
<ul class="todo-list">
<!-- v-for: Loop setiap tugas di array `todos` dan tampilkan -->
<li v-for="todo in todos" :key="todo.id" class="todo-item" :class="{ completed: todo.completed }">
<span @click="toggleComplete(todo.id)" class="todo-text">{{ todo.text }}</span>
<div class="actions">
<button @click="toggleComplete(todo.id)" class="action-button complete-button">
{{ todo.completed ? 'Batalin' : 'Selesai' }}
</button>
<button @click="removeTodo(todo.id)" class="action-button remove-button">Hapus</button>
</div>
</li>
<li v-if="todos.length === 0" class="no-tasks">
Waktunya rebahan? Eh, maksudnya, belum ada tugas nih! 😎
</li>
</ul>
</div>
</template>
<style scoped>
/* --- STYLING AKAN DITAMBAHKAN DI SINI --- */
.todo-app-container {
background-color: #fff;
padding: 30px;
border-radius: 10px;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
width: 100%;
max-width: 500px;
margin: 20px; /* Memberikan margin agar tidak terlalu mepet dengan pinggir */
box-sizing: border-box;
}
h1 {
text-align: center;
color: #333;
margin-bottom: 30px;
font-size: 2.2em;
}
.input-section {
display: flex;
margin-bottom: 25px;
gap: 10px; /* Jarak antar input dan button */
}
.todo-input {
flex-grow: 1;
padding: 12px 15px;
border: 2px solid #ddd;
border-radius: 8px;
font-size: 1em;
transition: border-color 0.3s ease;
}
.todo-input:focus {
outline: none;
border-color: #4CAF50;
}
.add-button {
background-color: #4CAF50;
color: white;
border: none;
padding: 12px 20px;
border-radius: 8px;
cursor: pointer;
font-size: 1em;
transition: background-color 0.3s ease;
white-space: nowrap; /* Mencegah tombol "Tambah" wrap */
}
.add-button:hover {
background-color: #45a049;
}
.todo-list {
list-style: none;
padding: 0;
}
.todo-item {
display: flex;
justify-content: space-between;
align-items: center;
background-color: #f9f9f9;
border: 1px solid #eee;
padding: 15px;
margin-bottom: 10px;
border-radius: 8px;
transition: background-color 0.3s ease;
word-break: break-word; /* Memastikan teks panjang tidak merusak layout */
}
.todo-item:hover {
background-color: #f0f0f0;
}
.todo-item.completed {
background-color: #e6ffe6; /* Warna lebih soft untuk completed */
border-left: 5px solid #4CAF50;
opacity: 0.7;
}
.todo-item.completed .todo-text {
text-decoration: line-through;
color: #888;
}
.todo-text {
flex-grow: 1;
cursor: pointer;
font-size: 1.1em;
color: #333;
}
.actions {
display: flex;
gap: 8px;
margin-left: 15px; /* Memberikan sedikit jarak */
flex-shrink: 0; /* Mencegah actions menyusut */
}
.action-button {
border: none;
padding: 8px 12px;
border-radius: 5px;
cursor: pointer;
font-size: 0.9em;
transition: background-color 0.3s ease, opacity 0.3s ease;
white-space: nowrap; /* Mencegah teks tombol wrap */
}
.complete-button {
background-color: #007bff;
color: white;
}
.complete-button:hover {
background-color: #0056b3;
}
.remove-button {
background-color: #dc3545;
color: white;
}
.remove-button:hover {
background-color: #c82333;
}
.no-tasks {
text-align: center;
color: #888;
font-style: italic;
margin-top: 30px;
}
</style>
Spill Dikit Penjelasan Kodenya:
<script setup>: Ini fitur baru di Vue 3 yang bikin setup komponen jadi lebih ringkas. Variabel atau fungsi yang dideklarasikan di sini auto bisa dipake di<template>tanpa perlureturnlagi.ref(): Dipake buat bikin variabel jadi reactive. Artinya, kalonewTodo.valueatautodos.valueberubah, Vue bakal auto update tampilan yang pake data itu.v-model="newTodo": Ini two-way data binding. Artinya, apa yang kita ketik di<input>, langsung disimpan ke variabelnewTodo. Sebaliknya, kalonewTodoberubah, isi<input>juga ikut berubah.@keyup.enter="addTodo": Ini event listener. Kalo kita ketik sesuatu di<input>terus tekanEnter, fungsiaddTodobakal langsung jalan. Praktis!v-for="todo in todos": Vue bakal ngulang<li ...>ini buat setiap objektodoyang ada di arraytodos.:key="todo.id": Penting banget buatv-for! Ini ngasih identitas unik ke setiap item di daftar, biar Vue bisa nge-update daftar secara efisien.:class="{ completed: todo.completed }": Ini dynamic class binding. Kalotodo.completeditutrue, Vue bakal nambahin classcompletedke<li >.onMounted&watch: Ini dipake buat fitur "persist data". Jadi, tugas yang udah kamu tambahin nggak bakal ilang kalo browsernya di-refresh. Kita simpan datanya kelocalStoragebrowser.onMounted: Fungsinya jalan sekali pas komponen pertama kali muncul. Kita pake buat ngambil data darilocalStoragekalo ada.watch: Fungsinya ngawasin arraytodos. Setiap ada perubahan ditodos(tambah, hapus, ubah status),watchbakal nyimpen datatodosterbaru kelocalStorage.{ deep: true }itu penting biarwatchtau kalo ada perubahan di dalam objek tugas (misalcompleted: true/false).
Tips Praktis & Best Practices (Biar Makin Jago!)
- Komponen Lebih Kecil: Kalau aplikasi makin gede, pecah
TodoList.vuejadi komponen-komponen yang lebih kecil (misalTodoItem.vuebuat satu item tugas). Biar makin rapi, ngab! Ini namanya component-based architecture. - Validasi Input Lebih Canggih: Tambahin validasi lebih lanjut. Misal, ada batas karakter, atau kasih notifikasi ke user kalo inputnya kosong.
- Styling Lebih Interaktif: Kamu bisa tambahin animasi kecil pake CSS Transition/Animation pas nambah atau hapus tugas, biar tampilannya makin hidup.
- State Management: Buat aplikasi yang lebih kompleks dan banyak data yang dibagi antar komponen, coba pelajari Pinia (manajemen state resmi Vue) atau Vuex. Ini worth it banget buat diulik!
- Routing: Pengen ada halaman lain di aplikasi kamu? Coba pelajari Vue Router!
- Error Handling: Gimana kalo
localStoragepenuh atau ada error lain? Kamu bisa tambahintry...catchbuat handle itu.
Kesimpulan
Gimana, gaes? Mantul kan bikin aplikasi To-Do List pake Vue Js? Dari yang awalnya cuma ide, sekarang udah jadi aplikasi fungsional yang bisa kamu pake sendiri. Ini baru permulaan lho! Vibes-nya Vue Js itu super user-friendly dan powerful. Jadi, jangan ragu buat eksplor lebih jauh lagi, ya. Coba modifikasi, tambahin fitur, atau bahkan bikin aplikasi lain!
Ingat, kunci dari jadi developer yang jago itu adalah terus belajar dan mencoba. Keep coding, keep creating! Kalo ada pertanyaan atau pengen spill project-mu, jangan sungkan ya! Sampai ketemu di proyek berikutnya!
Berikan Rating
Komentar (0)
Silakan login untuk memberikan komentar.
Login SekarangKata Kunci
Menyukai Artikel (0)
Belum ada siswa yang menyukai artikel ini.
Pembaca (0)
Belum ada user yang membaca artikel ini.
Belum ada komentar. Jadilah yang pertama!