Yuk, Gaspol! Bikin Aplikasi To-Do List Simpel Nan Kece Pake Vue Js (Anti Ribet, Auto Pro!)

Bikin To-Do List Simpel dengan Vue JS: Panduan Praktis & Cepat

PPLG

PPLG

Penulis

18 Jul 2026
11 x dilihat

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 perlu return lagi.
  • ref(): Dipake buat bikin variabel jadi reactive. Artinya, kalo newTodo.value atau todos.value berubah, 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 variabel newTodo. Sebaliknya, kalo newTodo berubah, isi <input> juga ikut berubah.
  • @keyup.enter="addTodo": Ini event listener. Kalo kita ketik sesuatu di <input> terus tekan Enter, fungsi addTodo bakal langsung jalan. Praktis!
  • v-for="todo in todos": Vue bakal ngulang <li ...> ini buat setiap objek todo yang ada di array todos.
  • :key="todo.id": Penting banget buat v-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. Kalo todo.completed itu true, Vue bakal nambahin class completed ke <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 ke localStorage browser.
    • onMounted: Fungsinya jalan sekali pas komponen pertama kali muncul. Kita pake buat ngambil data dari localStorage kalo ada.
    • watch: Fungsinya ngawasin array todos. Setiap ada perubahan di todos (tambah, hapus, ubah status), watch bakal nyimpen data todos terbaru ke localStorage. { deep: true } itu penting biar watch tau kalo ada perubahan di dalam objek tugas (misal completed: true/false).

Tips Praktis & Best Practices (Biar Makin Jago!)

  • Komponen Lebih Kecil: Kalau aplikasi makin gede, pecah TodoList.vue jadi komponen-komponen yang lebih kecil (misal TodoItem.vue buat 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 localStorage penuh atau ada error lain? Kamu bisa tambahin try...catch buat 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!


0.0

Berikan Rating

Komentar (0)

Silakan login untuk memberikan komentar.

Login Sekarang

Belum ada komentar. Jadilah yang pertama!

Menyukai Artikel (0)

Belum ada siswa yang menyukai artikel ini.

Pembaca (0)

Belum ada user yang membaca artikel ini.