Konsep powerful Vue v-model: Membuat custom dan reusable modal

Mohammad Sulthan
5 min readMar 26, 2023

--

Photo by La-Rel Easter on Unsplash

Use case kali ini sering kita temui tapi banyak yang masih bingung gimana implementasinya.

Sesuai janji di artikel atas, saya akan coba bikin satu artikel lagi masih dengan topik yang sama seputar v-model di Vue. Kita akan coba bahas 1 konsep Vue, menggunakan 1 use case spesifik. Harapannya, konsep ini bisa kamu implementasikan di use case lainnya. Cukup pahami konsep saja.

Background

Jadi, baru-baru ini saya diminta bikin 1 halaman web yang isinya list file dokumen yang di-upload sama user. Nantinya, di halaman ini bakal ada 1 tombol utama yang memungkinan user untuk upload satu atau beberapa dokument sekaligus.

Kira-kira sketch nya akan seperti ini:

List dokumen
List dokumen dengan modal

Persiapan

Kita mulai dari menginstall Vue 2. (Cara install Vue tidak akan saya jelaskan disini, silahkan pelajari secara mandiri). Disini kita akan coba pakai framework UI BootstrapVue (https://bootstrap-vue.org/docs).

Untuk menampilkan data ke dalam table, kita akan gunakan data dari `https://dummyjson.com/products`.

Action

Untuk memulai tahap coding, kita perlu memanggil API dari fileApp.vue , yang nantinya data tersebut akan kita passing ke component ProductList.vue (belum kita bikin).

Begini cara saya passing data dari API ke component ProductList.vue :

App.vue

Setelah itu, kita bikin 1 folder baru di dalam folder src, yaitu Component. Kemudian kita akan coba bikin file ProductList.vue di dalam folder tsb, yang isinya adalah table dari product itu sendiri begini hasil akhirnya:

ProductList.vue

Lanjut, sekarang kita perlu bikin file modalnya di dalam folder components. Modal ini fungsinya cuma buat liat informasi lebih banyak dari product yang kita klik di table ProductList.vue. Kita kasih nama ProductModal.vue . Hasilnya begini:

ProductModal.vue

Sampai disini, kita belum menambahkan component ProductModal.vue ke dalam vue app kita. Kita harus import file ini supaya button nya bisa tampil.

Sekarang kita balik ke file ProductList.vue , modifikasi file tersebut jadi seperti ini:

ProductList.vue

Dan harusnya sekarang sudah tampil seperti ini:

Tampilan saat ini

Bagian penting

Ok sekarang kita udah bisa menampilkan seluruh data dari API ke dalam table. Tapi data-nya masih belum diolah. Kalau di-scroll secara horizontal, ada 1 column yang title nya images dan thumbnail. Nanti nya kita bakal custom data table ini menjadi hanya menampikan 3–4 data saja, jadi user tidak perlu scroll horizontally untuk melihat keseluruhan data. Cukup klik product title nya, maka akan menampilkan seluruh detail data.

Mari kita bikin modal nya muncul dulu.

Di component ProductModal.vue , kita akan “menangkap” variabel bertipe boolean dari ProductList.vue yaitu berupa flag yang bernilai false untuk menutup modal, dan bernilai true untuk menangkap modal.

Modifikasi script di ProductModal.vue menjadi seperti ini:

ProductModal.vue

Disini kita akan menangkap property “value” dari ProductList.vue dan akan kita pakai value tersebut untuk menampilkan/menutup modal. Lebih lanjut, kita bakal modifikasi file ini dengan urutan berikut:

  1. Hapus data options.
  2. Ganti click listener di button “Open modal” menjadi “value != value”
  3. Ganti value v-model dari component <b-modal /> dari “modalShow” menjadi “value”.

Lalu di file ProductList.vue , kita perlu modifikasi file nya:

  1. Tambahkan v-model di component <product-modal />
  2. Tambahkan data options isModalShow: false .

Hasilnya akan jadi seperti ini:

ProductModal.vue
ProductList.vue

Pertanyaannya: kenapa props nya “value” tapi yang kita lempar itu adalah “v-model”?

Nah, penjelasan konsepnya sudah saya jelaskan di artikel saya sebelumnya:

https://medium.com/r/?url=https%3A%2F%2Fmohsulthana.medium.com%2Fapa-yang-sebenarnya-terjadi-di-balik-layar-v-model-vuejs-5c03dc797bd4

Jadi, intinya adalah, “value” di props component ProductModal.vue , yang ini:

Props value

Menangkap isi dari modifier v-model yang kita lempar di component ProductList.vue . Karena sejatinya v-model itu adalah shorthand dari

value="value" @input=" x => value = x.target.value"

Yang mana dia sebenarnya melempar isi dari variable “value”. Dan isi “value” itu ditangkap di child component ProductModal.vue sebagai prop “value”.

Saya agak kesulitan menjelaskan prinsip itu, tapi semoga penjelasan saya mudah dipahami.

Bug

Dari kode di atas, kita menemukan 1 bug yaitu di mana props value itu sebenarnya tidak boleh mutasi/dimodifikasi secara langsung, karena mutating prop itu sudah termasuk anti-pattern.

Penjelasannya sudah banyak ada di Google. Salah satunya bisa dibaca di sini:

Jadi, gimana cara kita solve bug ini?

Caranya, modifikasi component ProductModal.vue jadi begini:

  1. Bikin computed property untuk toggle isi variable dari prop “value”, misalnya “isModalOpen”.
  2. Binding value dari “isModalOpen” ke v-model component <b-modal />

Hasilnya begini:

ProductModal.vue

Ketika dijalankan, maka hasilnya akan jadi seperti ini:

Kita bakal membuat modal ini menjadi “lebih bermakna” dengan passing data product sesuai yang diklik di table.

Dengan sedikit modifikasi menambahkan data API di component ProductModal.vue , ketika kita meng-klik salah satu item di table maka kita akan mendapatkan hasil seperti ini:

Code lengkap nya bisa dilihat di sini:

Sekian dan terima kasih!

--

--

Mohammad Sulthan
Mohammad Sulthan

Written by Mohammad Sulthan

iOS Developer at Apple Developer Academy | IL. Love to code. Hardcore minimalist.

No responses yet