Form & v-model — Vue

v-model adalah two-way binding — menghubungkan data dengan form input secara otomatis. const name = ref("") const agreed = ref(false) ---template--- Halo, {{…

v-model mengikat sebuah kolom form dengan data reaktif ke dua arah: mengetik mengubah datanya, dan mengubah datanya mengubah isi kolom. Ini disebut two-way binding. Bayangin papan tulis kecil di meja kasir Warung Bu Sri yang dipakai berdua. Pembeli menulis pesanannya di papan, Bu Sri membaca dari papan yang sama. Kalau Bu Sri menghapus tulisan "pedas" karena cabainya habis, pembeli langsung melihatnya terhapus. Satu papan, dua arah. v-model membuat kolom form dan ref jadi satu papan seperti itu.

🧪 Tebakan cepat: Ada const nasi = ref(0) dan const teh = ref(0), dua kolom <input v-model="nasi" /> dan <input v-model="teh" />, lalu <p>Total porsi: {{ nasi + teh }}</p>. Pembeli mengganti isi kolom pertama jadi 1 dan kolom kedua jadi 2. Total porsinya berapa? Tebak dulu, jawabannya ada di bagian ".number, .trim, .lazy".

v-model: kolom dan data jadi satu

const nama = ref("")

---template---
<input v-model="nama" placeholder="Nama pemesan" />
<p>Pesanan atas nama: {{ nama }}</p>
<button @click="nama = ''">Hapus</button>
Kejadian nama Isi kolom Paragraf
Halaman tampil "" kosong Pesanan atas nama:
Ketik "Sri" "Sri" Sri Pesanan atas nama: Sri
Klik Hapus "" kosong Pesanan atas nama:

Checkbox, radio, select, dan textarea

const bungkus = ref(false)
const tambahan = ref([])
const pedas = ref("Sedang")
const menu = ref("Mie Ayam")
const catatan = ref("")

---template---
<label><input type="checkbox" v-model="bungkus" /> Dibungkus</label>

<label><input type="checkbox" value="Telur" v-model="tambahan" /> Telur</label>
<label><input type="checkbox" value="Kerupuk" v-model="tambahan" /> Kerupuk</label>

<label><input type="radio" value="Tidak pedas" v-model="pedas" /> Tidak pedas</label>
<label><input type="radio" value="Sedang" v-model="pedas" /> Sedang</label>
<label><input type="radio" value="Pedas" v-model="pedas" /> Pedas</label>

<select v-model="menu">
  <option>Nasi Goreng</option>
  <option>Mie Ayam</option>
  <option>Es Teh</option>
</select>

<textarea v-model="catatan"></textarea>
Elemen Isi data Contoh
Satu checkbox true atau false centang Dibungkus: bungkus jadi true
Beberapa checkbox, satu array array berisi value yang dicentang centang Kerupuk lalu Telur: ["Kerupuk", "Telur"]
Radio value yang dipilih pilih Pedas: "Pedas"
Select value opsi yang dipilih, atau teksnya kalau gak ada value dari awal Mie Ayam terpilih
Textarea teksnya "tanpa sayur"

.number, .trim, .lazy

const nasi = ref(0)
const teh = ref(0)

---template---
<input v-model="nasi" /> porsi Nasi Goreng
<input v-model="teh" /> gelas Es Teh
<p>Total porsi: {{ nasi + teh }}</p>
Ditulis nasi sesudah diisi 1 Total, sesudah diisi 1 dan 2
v-model="nasi" "1", teks 12
v-model.number="nasi" 1, angka 3

Tanpa .number, totalnya 12. Itu jawaban tebakannya. Isi kolom input selalu teks, jadi "1" + "2" menyambung teks, bukan menjumlah angka. Perkalian kebetulan tetap benar ("1" * 15000 jadi 15000), dan karena itu bug ini sering lolos.

Modifier Yang dilakukan Contoh
.number mengubah isi kolom jadi angka "2 porsi" jadi 2; "dua" tetap teks "dua" karena gak bisa jadi angka
.trim membuang spasi di awal dan akhir " Sri " jadi "Sri"
.lazy baru menulis ke data saat event change, yaitu saat kolom ditinggalkan atau Enter ditekan mengetik "Sri" belum mengubah nama

⚠️ Jebakan yang sering ketemu

TL;DR: v-model="nama" mengikat kolom form dan ref ke dua arah: mengetik mengubah data, mengubah data mengubah kolom. Kolom teks dan textarea memberi teks, satu checkbox memberi true atau false, beberapa checkbox dengan ref([]) memberi array value yang dicentang, radio dan select memberi value yang dipilih, dan nilai awal ref menentukan apa yang terpilih. Isi kolom selalu teks, jadi .number mengubahnya jadi angka; .trim membuang spasi di ujung; .lazy menunggu event change. Atribut value diabaikan, dan isi v-model harus ref atau properti yang bisa ditulis.

Yang akan kamu pelajari