Vue.js adalah salah satu framework JavaScript paling populer untuk membangun antarmuka web yang reaktif. Dengan sintaks yang ramah pemula, performa tinggi, dan ekosistem yang matang, Vue menjadi pilihan favorit banyak developer Indonesia. Pada tutorial ini, kamu akan belajar Vue.js 3 dari nol menggunakan Composition API — mulai dari reactive state, directive, computed, hingga komponen — dan diakhiri dengan membangun aplikasi todo list yang berfungsi penuh. Jika kamu belum paham dasar JavaScript, sebaiknya baca dulu artikel Memahami Dasar JavaScript: Variabel, Fungsi, dan DOM.

Apa Itu Vue.js?

Vue.js (atau cukup disebut Vue) adalah framework JavaScript progresif untuk membangun user interface. Disebut progresif karena kamu bisa memakainya sekecil apa pun — cukup satu halaman dengan satu komponen — lalu berkembang perlahan menjadi aplikasi SPA (Single Page Application) yang kompleks. Vue diciptakan oleh Evan You pada tahun 2014 dan kini dikelola oleh tim inti bersama komunitas yang sangat aktif.

Kenapa Memilih Vue.js?

Ada beberapa alasan mengapa Vue layak kamu pelajari. Pertama, kurva belajarnya landai: sintaksnya memadukan template HTML yang familiar dengan JavaScript, sehingga terasa natural bagi kamu yang sudah terbiasa menulis HTML. Kedua, reaktivitasnya otomatis — perubahan data langsung memperbarui tampilan tanpa perlu manipulasi DOM manual. Ketiga, dokumentasi resminya sangat lengkap dan mudah dipahami. Terakhir, ekosistemnya matang dengan Vue Router, Pinia, dan Vite. Dibandingkan dengan Belajar React untuk Pemula: Komponen, State, dan Props yang lebih berorientasi JavaScript murni (JSX), Vue menawarkan pendekatan template yang lebih dekat dengan HTML biasa.

Persiapan Lingkungan

Kamu membutuhkan Node.js versi 18 ke atas dan npm (sudah ikut terinstal bersama Node). Cek instalasimu dengan perintah berikut:

bash
node --version
npm --version

Jika keduanya menampilkan nomor versi, kamu siap lanjut. Sekarang buat proyek baru menggunakan create-vue, scaffolding resmi Vue:

bash
npm create vue@latest

# Tekan Enter untuk semua pertanyaan (pilih opsi default),
# lalu jalankan:
cd nama-proyek-kamu
npm install
npm run dev

Tips: Setelah npm run dev, buka alamat yang ditampilkan di terminal (biasanya http://localhost:5173). Halaman akan otomatis reload setiap kali kamu menyimpan perubahan — fitur ini disebut Hot Module Replacement (HMR).

Konsep 1: Reactive State dengan ref()

Inti dari Vue adalah reaktivitas. Dengan ref(), kita membuat variabel reaktif yang otomatis memperbarui template ketika nilainya berubah. Buka file src/App.vue dan ganti isinya dengan kode berikut:

html
<script setup>
import { ref } from 'vue'

const count = ref(0)

function increment() {
  count.value++
}
</script>

<template>
  <div class="counter">
    <h1>Hitungan: {{ count }}</h1>
    <button @click="increment">Tambah</button>
  </div>
</template>

Perhatikan dua hal penting. Pertama, di dalam <script setup> kamu mengakses nilai ref lewat count.value (perlu .value), sedangkan di dalam template cukup {{ count }} (Vue otomatis membukanya). Kedua, @click adalah singkatan dari v-on:click untuk menangani event klik.

Konsep 2: Directive — v-if, v-for, v-bind, dan v-model

Directive adalah atribut khusus berawalan v- yang memberi instruksi pada DOM. Berikut directive yang paling sering dipakai:

html
<script setup>
import { ref } from 'vue'

const items = ref(['Belajar HTML', 'Belajar JavaScript', 'Belajar Vue.js'])
const newItem = ref('')
const isAdmin = ref(true)

function addItem() {
  if (newItem.value.trim()) {
    items.value.push(newItem.value.trim())
    newItem.value = ''
  }
}
</script>

<template>
  <!-- v-if / v-else: render bersyarat -->
  <p v-if="isAdmin">Halo, Admin! 👋</p>
  <p v-else>Halo, Pengunjung!</p>

  <!-- v-for: render daftar -->
  <ul>
    <li v-for="(item, index) in items" :key="index">{{ item }}</li>
  </ul>

  <!-- v-model: two-way binding + v-on:keyup -->
  <input v-model="newItem" @keyup.enter="addItem" placeholder="Tambah item" />
  <button @click="addItem">Tambah</button>
</template>

Penjelasan singkat: v-if/v-else untuk menampilkan elemen secara kondisional, v-for untuk mengulang daftar (selalu beri :key yang unik), :key adalah bentuk singkat dari v-bind:key, dan v-model untuk two-way binding antara input dan variabel reaktif.

Konsep 3: Computed dan Watch

computed menghasilkan nilai turunan yang otomatis dihitung ulang saat dependency-nya berubah, sedangkan watch menjalankan aksi tertentu saat sebuah nilai berubah. Keduanya sering tertukar, jadi perhatikan contohnya:

html
<script setup>
import { ref, computed, watch } from 'vue'

const harga = ref(100000)
const jumlah = ref(1)

// computed: dihitung ulang otomatis saat dependency berubah
const total = computed(() => harga.value * jumlah.value)

// watch: bereaksi saat sebuah nilai berubah
watch(jumlah, (baru, lama) => {
  console.log(`Jumlah berubah dari ${lama} ke ${baru}`)
})
</script>

<template>
  <p>Harga: {{ harga.toLocaleString('id-ID') }}</p>
  <input v-model.number="jumlah" type="number" min="1" />
  <p>Total: {{ total.toLocaleString('id-ID') }}</p>
</template>

Aturan praktisnya: gunakan computed untuk menurunkan nilai (seperti total harga), dan gunakan watch untuk efek samping (seperti memanggil API atau menyimpan ke localStorage saat nilai berubah).

Konsep 4: Komponen, Props, dan Emits

Komponen membuat aplikasi tersusun dari bagian-bagian kecil yang bisa dipakai ulang. Data mengalir dari induk ke anak lewat props, dan dari anak ke induk lewat emit. Konsep ini mirip dengan props di tutorial React. Buat file src/components/TodoItem.vue:

html
<!-- src/components/TodoItem.vue -->
<script setup>
const props = defineProps({
  todo: { type: Object, required: true }
})

const emit = defineEmits(['toggle', 'remove'])
</script>

<template>
  <li :class="{ done: todo.done }">
    <input
      type="checkbox"
      :checked="todo.done"
      @change="emit('toggle', todo.id)"
    />
    <span>{{ todo.text }}</span>
    <button @click="emit('remove', todo.id)">Hapus</button>
  </li>
</template>

<style scoped>
.done span {
  text-decoration: line-through;
  color: #999;
}
</style>

Proyek Lengkap: Aplikasi Todo List

Sekarang kita gabungkan semua konsep di atas menjadi aplikasi todo list yang berfungsi penuh. Ubah src/App.vue menjadi seperti ini:

html
<script setup>
import { ref, computed } from 'vue'
import TodoItem from './components/TodoItem.vue'

const todos = ref([
  { id: 1, text: 'Belajar JavaScript', done: true },
  { id: 2, text: 'Belajar Vue.js', done: false },
])
const newTodo = ref('')

const sisa = computed(() => todos.value.filter(t => !t.done).length)

function addTodo() {
  const text = newTodo.value.trim()
  if (!text) return
  todos.value.push({ id: Date.now(), text, done: false })
  newTodo.value = ''
}

function toggle(id) {
  const todo = todos.value.find(t => t.id === id)
  if (todo) todo.done = !todo.done
}

function remove(id) {
  todos.value = todos.value.filter(t => t.id !== id)
}
</script>

<template>
  <div class="app">
    <h1>📝 Todo List</h1>

    <div class="input-group">
      <input
        v-model="newTodo"
        @keyup.enter="addTodo"
        placeholder="Apa yang harus dikerjakan?"
      />
      <button @click="addTodo">Tambah</button>
    </div>

    <p class="count">Sisa {{ sisa }} dari {{ todos.length }} tugas</p>

    <ul>
      <TodoItem
        v-for="todo in todos"
        :key="todo.id"
        :todo="todo"
        @toggle="toggle"
        @remove="remove"
      />
    </ul>
  </div>
</template>

<style scoped>
.app { max-width: 480px; margin: 0 auto; font-family: sans-serif; }
.input-group { display: flex; gap: 8px; }
.input-group input { flex: 1; padding: 8px; }
.count { color: #666; font-size: 14px; }
</style>

Simpan file dan buka browser — sekarang kamu punya todo list interaktif: bisa menambah, menandai selesai, dan menghapus tugas, dengan penghitung sisa tugas yang otomatis diperbarui. Ingin tampilannya lebih cantik? Kamu bisa memadukannya dengan Belajar Tailwind CSS. Dan kalau ingin data todo tersimpan permanen di server, lanjutkan dengan membangun backend menggunakan Membuat REST API dengan Node.js dan Express.

Langkah selanjutnya: pelajari Vue Router untuk navigasi antar halaman, Pinia untuk state management global, dan lifecycle hooks seperti onMounted untuk memanggil data dari API saat komponen dimuat. Ketiganya adalah pondasi untuk membangun aplikasi Vue yang siap produksi.

Kesimpulan

Selamat! Kamu telah memahami fondasi Vue.js 3: reactive state dengan ref(), directive (v-if, v-for, v-bind, v-model), computed dan watch, serta komponen dengan props dan emit — dan berhasil membangun aplikasi todo list yang berfungsi penuh. Dari sini, kamu siap menjelajahi fitur lanjutan dan membangun aplikasi web reaktif yang lebih besar. Selamat ngoding!

Apakah saya harus menguasai JavaScript dulu sebelum belajar Vue.js?

Sangat disarankan. Vue.js dibangun di atas JavaScript, jadi pemahaman dasar tentang variabel, fungsi, array, dan DOM akan membuat proses belajarmu jauh lebih lancar. Kamu bisa memulai dari artikel Memahami Dasar JavaScript: Variabel, Fungsi, dan DOM.

Apa perbedaan Vue.js dan React?

Keduanya adalah framework populer untuk membangun UI reaktif. React menggunakan JSX (JavaScript murni) dan lebih fleksibel, sedangkan Vue memakai template HTML yang lebih dekat dengan markup biasa sehingga terasa lebih ramah pemula. Pilihan terbaik tergantung preferensi dan kebutuhan proyekmu — kamu bisa membandingkannya lewat Belajar React untuk Pemula.

Apakah Vue.js cocok untuk pemula?

Ya, Vue sering dianggap sebagai framework JavaScript yang paling ramah pemula karena sintaks templatenya intuitif dan dokumentasinya sangat lengkap. Kamu bahkan bisa mulai tanpa build tool hanya dengan menyertakan Vue lewat CDN.