Form Input Binding dengan v-model
Binding dua arah v-model untuk text, textarea, checkbox, radio, dan select, plus modifier .lazy, .number, .trim.
Binding dua arah
Di bab sebelumnya data mengalir satu arah: dari script ke tampilan. Pada form, kita butuh arah sebaliknya juga: apa yang diketik pengguna harus masuk ke variabel. v-model melakukan keduanya sekaligus — itu sebabnya disebut two-way binding.
<input v-model="nama">
<p>Halo, {{ nama }}</p>
const nama = ref('')
Ketik di kolom → nama berubah → paragraf ikut berubah. Mengubah nama.value lewat kode juga mengubah isi kolom.
v-model hanyalah singkatan dari :value="nama" + @input="nama = $event.target.value". Kamu bisa menulisnya manual, tapi tidak perlu.
Jenis-jenis input
| Elemen | Contoh | Tipe data |
|---|---|---|
| Teks | <input v-model="nama"> | String |
| Textarea | <textarea v-model="catatan"> | String |
| Checkbox tunggal | <input type="checkbox" v-model="setuju"> | Boolean |
| Checkbox banyak | v-model="hobi" + value="..." | Array |
| Radio | <input type="radio" value="A" v-model="pilihan"> | Nilai value |
| Select | <select v-model="kota"> | Nilai value option |
<!-- checkbox banyak -->
<label><input type="checkbox" value="baca" v-model="hobi"> Baca</label>
<label><input type="checkbox" value="game" v-model="hobi"> Game</label>
const hobi = ref([]) // ['baca', 'game']
<!-- radio -->
<label><input type="radio" value="pemula" v-model="level"> Pemula</label>
<label><input type="radio" value="mahir" v-model="level"> Mahir</label>
<!-- select -->
<select v-model="kota">
<option disabled value="">Pilih kota</option>
<option>Jakarta</option>
<option>Bandung</option>
</select>
Modifier
| Modifier | Fungsi |
|---|---|
.lazy | Sinkron saat event change (setelah selesai mengetik), bukan setiap ketikan |
.number | Ubah input menjadi angka otomatis |
.trim | Hapus spasi di awal & akhir |
<input v-model.trim="nama">
<input type="number" v-model.number="umur">
<input v-model.lazy="judul">
Tanpa .number, nilai dari <input type="number"> tetap bisa berupa string pada beberapa kasus, sehingga umur + 1 bisa menjadi "251" bukan 26.
Contoh form lengkap
<form @submit.prevent="daftar">
<input v-model.trim="form.nama" placeholder="Nama">
<input type="email" v-model="form.email" placeholder="Email">
<button :disabled="!form.nama || !form.email">Daftar</button>
</form>
const form = reactive({ nama: '', email: '' })
Menyimpan seluruh isian dalam satu objek reactive membuat form besar lebih rapi.
Kesalahan umum
- Menulis
:valuesaja (tanpa@input): kolom hanya menampilkan, tidak mengubah data. v-modelpadaselecttanpaoptionbernilai awal → tampilan kosong di iOS. Beri<option disabled value="">.- Mengabaikan komposisi IME (huruf Jepang/Cina):
v-modeltidak berubah saat komposisi; gunakan:value+@inputbila perlu.