08 Agu 2025·6 menit membaca

Komponen Vue kustom di UI yang dihasilkan — aman saat regenerasi

Pelajari cara menambahkan komponen Vue kustom ke UI yang dihasilkan tanpa merusak regenerasi, dengan pola isolasi, batas yang jelas, dan aturan serah terima sederhana.

Komponen Vue kustom di UI yang dihasilkan — aman saat regenerasi

Apa yang rusak ketika Anda mengedit UI yang dihasilkan

UI yang dihasilkan dimaksudkan untuk dibangun ulang. Di platform seperti AppMaster, kode aplikasi web Vue3 dibuat dari builder visual. Regenerasi adalah cara agar perubahan tetap konsisten di seluruh layar, logika, dan model data.

Masalahnya sederhana: jika Anda mengedit file yang dihasilkan secara langsung, regenerasi berikutnya bisa menimpa perubahan Anda.

Itulah sebabnya tim menambahkan kode kustom. Blok UI bawaan biasanya mencakup formulir dan tabel standar, tetapi aplikasi nyata biasanya membutuhkan beberapa bagian spesial: grafik kompleks, pemilih peta, editor teks kaya, papan tanda tangan, atau perencana drag-and-drop. Itu alasan yang baik untuk menambahkan komponen Vue kustom, selama Anda memperlakukan mereka sebagai tambahan, bukan suntingan langsung.

Saat kode kustom bercampur dengan kode yang dihasilkan, kegagalan bisa muncul terlambat dan membingungkan. Anda mungkin tidak menyadari sampai perubahan UI berikutnya memaksa regenerasi, atau sampai rekan tim mengubah layar di editor visual. Masalah umum meliputi:

  • Markup kustom Anda menghilang karena template dibuat ulang.
  • Impor atau registrasi rusak karena nama file atau struktur berubah.
  • "Perbaikan kecil" berubah menjadi konflik merge pada setiap deploy.
  • Logika yang dihasilkan dan logika kustom menyimpang, sehingga kasus tepi mulai gagal.
  • Upgrade terasa berisiko karena Anda tidak tahu apa yang akan diganti.

Tujuannya bukan menghindari kustomisasi. Tujuannya membuat rebuild dapat diprediksi. Jika Anda menjaga batas yang bersih antara layar yang dihasilkan dan widget kustom, regenerasi tetap rutin daripada menyiksa.

Aturan batas yang menjaga regenerasi tetap aman

Jika Anda ingin kustomisasi tanpa kehilangan pekerjaan, ikuti satu aturan: jangan pernah mengedit file yang dihasilkan. Perlakukan mereka sebagai output hanya-baca, seperti artefak terkompilasi.

Pikirkan UI Anda sebagai dua zona:

  • Zona yang dihasilkan: halaman, layout, dan layar yang diproduksi oleh generator.
  • Zona kustom: komponen Vue yang Anda tulis sendiri di folder terpisah.

UI yang dihasilkan harus mengonsumsi komponen kustom Anda. Itu bukan tempat untuk membangun komponen tersebut.

Agar bekerja dalam jangka panjang, kecilkan dan perjelas "perbatasan". Sebuah widget kustom harus berperilaku seperti produk kecil dengan kontrak:

  • Props masuk: hanya apa yang dibutuhkan untuk dirender.
  • Events keluar: hanya apa yang perlu direspon oleh halaman.

Hindari menjangkau state global atau memanggil API yang tidak terkait dari dalam widget kecuali itu memang bagian eksplisit dari kontrak.

Dengan layar Vue3 bergaya AppMaster, ini biasanya berarti Anda melakukan sedikit pengkabelan di layar yang dihasilkan untuk meneruskan props dan menangani event. Pengkabelan itu mungkin berubah saat regenerasi, tetapi tetap kecil dan mudah diperbaiki. Pekerjaan nyata tetap aman di zona kustom.

Pola isolasi yang cocok dengan Vue3

Tujuannya sederhana: regenerasi harus bisa mengganti file yang dihasilkan secara bebas, sementara kode widget Anda tetap utuh.

Pendekatan praktis adalah menjaga widget khusus sebagai modul internal kecil: komponen, gaya, dan utilitas pembantu di satu tempat. Pada aplikasi Vue3 yang dihasilkan, itu biasanya berarti kode kustom berada di luar halaman yang dihasilkan dan diimpor sebagai dependency.

Komponen pembungkus (wrapper) sangat membantu. Biarkan wrapper berbicara dengan aplikasi yang dihasilkan: baca bentuk data halaman yang ada, normalisasikan, dan berikan props bersih ke widget. Jika bentuk data yang dihasilkan berubah nanti, Anda sering memperbarui wrapper alih-alih menulis ulang widget.

Beberapa pola yang tahan lama:

  • Perlakukan widget sebagai kotak hitam: props masuk, events keluar.
  • Gunakan wrapper untuk memetakan respons API, tanggal, dan ID ke format yang ramah widget.
  • Jaga gaya agar ter-scope sehingga halaman yang dihasilkan tidak sengaja menimpa widget Anda.
  • Jangan bergantung pada struktur DOM parent atau nama kelas halaman tertentu.

Untuk styling, utamakan CSS ter-scope (atau CSS Modules) dan beri namespace pada kelas bersama. Jika widget perlu cocok dengan tema aplikasi, kirim token tema sebagai props (warna, spasi, ukuran font) alih-alih mengimpor gaya halaman.

Slots bisa aman jika tetap kecil dan opsional, misalnya pesan "empty state". Jika slot mulai mengontrol tata letak inti atau perilaku, berarti Anda telah memindahkan widget kembali ke lapisan yang dihasilkan—di situlah rasa sakit regenerasi dimulai.

Merancang kontrak komponen yang stabil (props dan events)

Cara teraman agar regenerasi tetap mudah adalah memperlakukan setiap widget seperti antarmuka yang stabil. Layar yang dihasilkan bisa berubah. Komponen Anda tidak boleh.

Mulai dengan input (props). Buat sedikit, dapat diprediksi, dan mudah divalidasi. Pilih primitif sederhana dan objek polos yang Anda kontrol. Tambahkan default sehingga widget berperilaku baik meskipun halaman belum mengirim apa-apa. Jika sesuatu bisa salah format (ID, string tanggal, nilai seperti enum), validasi dan gagal secara lembut: tampilkan keadaan kosong daripada crash.

Untuk output, standarisasi event agar widget terasa konsisten dengan sisa aplikasi. Set yang dapat diandalkan misalnya:

  • update:modelValue untuk v-model
  • change untuk perubahan yang dikonfirmasi pengguna (bukan setiap ketikan)
  • error saat komponen tidak bisa menyelesaikan tugasnya
  • ready saat pekerjaan async selesai dan widget siap digunakan

Jika ada pekerjaan async, jadikan itu bagian dari kontrak. Ekspos props loading dan disabled, dan pertimbangkan errorMessage untuk kegagalan sisi server. Jika komponen mengambil data sendiri, tetap emit error dan ready agar parent bisa bereaksi (toast, logging, fallback UI).

Harapan aksesibilitas

Masukkan aksesibilitas ke dalam kontrak. Terima prop label (atau ariaLabel), dokumentasikan perilaku keyboard, dan jaga fokus agar dapat diprediksi setelah aksi.

Contohnya, widget timeline pada dashboard harus mendukung tombol panah untuk berpindah antar item, Enter untuk membuka detail, dan mengembalikan fokus ke kontrol yang membuka dialog saat dialog ditutup. Ini membuat widget bisa digunakan ulang di layar yang dihasilkan tanpa banyak pengerjaan ulang.

Langkah demi langkah: menambahkan widget khusus tanpa menyentuh file yang dihasilkan

Mix no-code and Vue3
Use the visual UI builder, then plug in bespoke Vue components as add-ons.
Build Web App

Mulai kecil: satu layar yang penting bagi pengguna, satu widget yang membuatnya terasa berbeda. Menjaga perubahan pertama sempit membuat lebih mudah melihat apa yang regenerasi pengaruhi dan yang tidak.

  1. Buat komponen di luar area yang dihasilkan. Letakkan di folder yang Anda miliki dan simpan di version control (seringkali custom atau extensions).

  2. Jaga permukaan publik kecil. Beberapa props masuk, beberapa events keluar. Jangan kirim seluruh state halaman.

  3. Tambahkan wrapper tipis yang Anda miliki juga. Tugasnya menerjemahkan "data halaman yang dihasilkan" ke kontrak widget.

  4. Integrasikan lewat titik ekstensi yang didukung. Referensikan wrapper dengan cara yang tidak memerlukan pengeditan file yang dihasilkan.

  5. Regenerate dan verifikasi. Folder custom, wrapper, dan komponen Anda harus tetap tidak berubah dan masih terkompilasi.

Jaga batas tetap tegas. Widget fokus pada tampilan dan interaksi. Wrapper memetakan data dan meneruskan aksi. Aturan bisnis tetap di lapisan logika aplikasi (backend atau proses bersama), bukan terkubur di dalam widget.

Pemeriksaan akal sehat: jika regenerasi terjadi sekarang, dapatkah rekan tim membangun ulang aplikasi dan mendapatkan hasil yang sama tanpa mengulangi suntingan manual? Jika ya, pola Anda solid.

Di mana meletakkan logika agar UI tetap mudah dipelihara

Widget kustom sebaiknya sebagian besar memikirkan tampilan dan respons terhadap input pengguna. Semakin banyak aturan bisnis Anda masukkan ke widget, semakin sulit untuk digunakan ulang, diuji, dan diubah.

Default yang baik: simpan logika bisnis di lapisan halaman atau fitur, dan buat widget tetap “bodoh”. Halaman memutuskan data apa yang diberikan ke widget dan apa yang terjadi saat widget emit event. Widget merender dan melaporkan niat pengguna.

Saat Anda membutuhkan logika dekat widget (formatting, state kecil, validasi sisi-klien), sembunyikan di balik lapisan service kecil. Dalam Vue3, itu bisa berupa module, composable, atau store dengan API yang jelas. Widget mengimpor API itu, bukan internals aplikasi secara acak.

Pembagian praktis:

  • Widget (komponen): state UI, penanganan input, visual, emit event seperti select, change, retry.
  • Service/composable: shaping data, caching, memetakan error API ke pesan pengguna.
  • Page/container: aturan bisnis, izin, data mana yang dimuat, kapan disimpan.
  • Bagian aplikasi yang dihasilkan: dibiarkan tidak tersentuh; kirim data masuk dan dengarkan event.

Hindari panggilan API langsung di dalam widget kecuali itu memang kontrak widget. Jika widget mengambil sendiri, buat itu jelas (beri nama seperti CustomerSearchWidget dan letakkan kode panggilan di satu service). Jika tidak, kirim items, loading, dan error sebagai props.

Pesan error harus ramah pengguna dan konsisten. Alih-alih menampilkan teks server mentah, petakan error ke beberapa pesan kecil yang dipakai di seluruh aplikasi, misalnya “Gagal memuat data. Coba lagi.” Sertakan aksi retry bila memungkinkan, dan catat error detail di luar widget.

Contoh: widget ApprovalBadge kustom tidak seharusnya memutuskan apakah faktur bisa disetujui. Biarkan halaman menghitung status dan canApprove. Badge emit approve, dan halaman menjalankan aturan sebenarnya dan memanggil backend, lalu mengirim status sukses atau error kembali ke UI.

Kesalahan umum yang menyebabkan sakit setelah regenerasi berikutnya

Use built-ins first
Lean on built-in auth and payments modules, then customize UI where it matters.
Use Modules

Kebanyakan masalah bukan soal Vue. Mereka muncul karena mencampur pekerjaan kustom ke tempat yang dikuasai generator, atau bergantung pada detail yang cenderung berubah.

Kesalahan yang paling sering mengubah widget kecil menjadi tugas pembersihan berulang:

  • Mengedit file Vue yang dihasilkan langsung dan lupa apa yang diubah.
  • Menggunakan CSS global atau selector luas yang diam-diam mempengaruhi halaman lain saat markup bergeser.
  • Membaca atau memodifikasi bentuk state yang dihasilkan secara langsung, sehingga perubahan nama memecah widget.
  • Memasukkan terlalu banyak asumsi spesifik halaman ke dalam satu komponen.
  • Mengubah API komponen (props/events) tanpa rencana migrasi.

Skenario umum: Anda menambahkan widget tabel kustom dan itu bekerja. Sebulan kemudian, perubahan layout yang dihasilkan membuat aturan global .btn Anda mempengaruhi halaman login dan admin. Atau objek data berubah dari user.name menjadi user.profile.name, dan widget gagal diam-diam. Widget bukan masalahnya—ketergantungan pada detail tidak stabil lah yang bermasalah.

Dua kebiasaan mencegah ini:

Pertama, perlakukan kode yang dihasilkan sebagai hanya-baca dan simpan file kustom terpisah, dengan boundary impor yang jelas.

Kedua, buat kontrak komponen kecil dan eksplisit. Jika perlu dikembangkan, tambahkan prop versi sederhana (mis. apiVersion) atau dukung bentuk prop lama dan baru untuk satu rilis.

Daftar pemeriksaan cepat sebelum Anda merilis komponen kustom

Keep logic out of widgets
Start with Data Designer and keep UI custom code focused on interaction only.
Model Data

Sebelum menggabungkan widget khusus ke aplikasi Vue3 yang dihasilkan, lakukan pemeriksaan realitas cepat. Komponen harus bertahan dari regenerasi berikutnya tanpa pahlawan, dan orang lain harus bisa menggunakannya kembali.

  • Uji regenerasi: jalankan regenerasi penuh dan bangun ulang. Jika Anda harus mengedit file yang dihasilkan ulang, batasnya salah.
  • Input dan output jelas: props masuk, emits keluar. Hindari dependensi magic seperti mengambil DOM eksternal atau mengasumsikan store halaman tertentu.
  • Kontain gaya: scope gaya dan gunakan prefix kelas yang jelas (misalnya timeline-).
  • Semua keadaan terlihat baik: loading, error, dan empty state harus hadir dan masuk akal.
  • Dapat dipakai ulang tanpa cloning: pastikan Anda bisa menaruhnya di halaman kedua hanya dengan mengubah props dan penangan event, bukan menyalin internal.

Cara cepat memvalidasi: bayangkan menambahkan widget ke halaman admin lalu ke portal pelanggan. Jika keduanya bekerja hanya dengan perubahan props dan handler event, Anda aman.

Contoh realistis: menambahkan widget timeline ke dashboard

Tim support sering ingin satu layar yang menceritakan riwayat tiket: perubahan status, catatan internal, balasan pelanggan, dan event pembayaran atau pengiriman. Widget timeline cocok, tapi Anda tidak ingin mengedit file yang dihasilkan dan kehilangan pekerjaan setelah regenerasi berikutnya.

Pendekatan aman: simpan widget terisolasi di luar UI yang dihasilkan dan letakkan di halaman melalui wrapper tipis.

Kontrak widget

Buat sederhana dan dapat diprediksi. Misalnya, wrapper mengirimkan:

  • ticketId (string)
  • range (7 hari terakhir, 30 hari terakhir, kustom)
  • mode (compact vs detailed)

Widget emit:

  • select saat pengguna klik event
  • changeFilters saat pengguna mengubah range atau mode

Sekarang widget tidak tahu apa-apa tentang halaman dashboard, model data, atau bagaimana permintaan dibuat. Ia merender timeline dan melaporkan aksi pengguna.

Cara wrapper menghubungkannya ke halaman

Wrapper berada di samping dashboard dan menerjemahkan data halaman ke kontrak. Ia membaca ticket ID dari state halaman, mengubah filter UI menjadi range, dan memetakan record backend ke format event yang diharapkan widget.

Saat widget emit select, wrapper bisa membuka panel detail atau memicu aksi halaman. Saat emit changeFilters, wrapper memperbarui filter halaman dan merefresh data.

Ketika UI dashboard di-regenerate, widget tetap tidak tersentuh karena berada di luar file yang dihasilkan. Biasanya Anda hanya perlu mengunjungi wrapper jika halaman mengganti nama field atau mengubah cara menyimpan filter.

Kebiasaan pengujian dan rilis yang mencegah kejutan

Design a stable widget API
Define a clean props-and-events contract so your widget stays stable across rebuilds.
Create Component

Komponen kustom biasanya gagal dengan cara membosankan: bentuk prop berubah, event berhenti terpanggil, atau halaman yang dihasilkan merender ulang lebih sering daripada yang widget harapkan. Beberapa kebiasaan menangkap masalah ini lebih awal.

Pengujian lokal: deteksi masalah boundary lebih awal

Perlakukan boundary antara UI yang dihasilkan dan widget Anda seperti API. Uji widget tanpa aplikasi penuh terlebih dahulu, dengan props hardcoded yang sesuai kontrak.

Render dengan props "jalur bahagia" dan dengan nilai yang hilang. Simulasikan event utama (simpan, batal, pilih) dan konfirmasi parent menanganinya. Uji data lambat dan layar kecil. Verifikasi widget tidak menulis ke state global kecuali itu bagian kontrak.

Jika Anda membangun di atas aplikasi AppMaster Vue3, jalankan pemeriksaan ini sebelum Anda meregenerate apa pun. Lebih mudah mendiagnosis masalah boundary ketika Anda tidak mengubah dua hal sekaligus.

Regresi setelah regenerasi: apa yang harus diperiksa dulu

Setelah setiap regenerasi, periksa kembali titik sentuh: apakah props yang sama masih dikirim, dan apakah event yang sama masih ditangani? Di situlah kerusakan biasanya muncul pertama.

Jaga inklusi tetap dapat diprediksi. Hindari impor rapuh yang bergantung pada jalur file yang mungkin berpindah. Gunakan satu titik masuk yang stabil untuk komponen kustom Anda.

Untuk produksi, tambahkan logging ringan dan penangkapan error di dalam widget:

  • Mounted dengan props kunci (yang telah disanitasi)
  • Pelanggaran kontrak (prop wajib hilang, tipe salah)
  • Panggilan API gagal dengan kode error singkat
  • Empty state tak terduga

Saat sesuatu rusak, Anda ingin cepat menjawab: apakah regenerasi mengubah input, atau widget yang berubah?

Langkah berikutnya: buat pola ini bisa diulang di seluruh aplikasi Anda

Setelah widget pertama berhasil, kemenangan sebenarnya adalah membuatnya bisa diulang sehingga yang berikutnya bukan hack sekali jadi.

Buat standar internal kecil untuk kontrak widget dan tuliskan di tempat tim menyimpan catatan aplikasi. Buat sederhana: penamaan, props wajib vs opsional, set event kecil, perilaku error, dan kepemilikan jelas (apa yang hidup di UI yang dihasilkan vs folder kustom Anda).

Tulis juga aturan boundary dalam bahasa sehari-hari: jangan edit file yang dihasilkan, isolasi kode kustom, dan kirim data hanya lewat props dan events. Ini mencegah "perbaikan cepat" yang berubah jadi pajak pemeliharaan permanen.

Sebelum membangun widget kedua, jalankan uji regenerasi kecil. Kirim widget pertama, lalu regenerate setidaknya dua kali selama perubahan normal (perubahan label, perubahan layout, field baru) dan pastikan tidak ada yang rusak.

Jika Anda menggunakan AppMaster, biasanya terbaik menyimpan sebagian besar UI dan logika di editor visual (UI builders, Business Process Editor, dan Data Designer). Simpan komponen Vue kustom untuk widget yang benar-benar unik yang editor tidak bisa ekspresikan, seperti timeline khusus, interaksi grafik, atau kontrol input yang tidak biasa. Jika Anda ingin titik awal yang bersih untuk pendekatan ini, AppMaster di appmaster.io dirancang di sekitar regenerasi, jadi menjaga widget kustom terisolasi menjadi bagian alami dari alur kerja.

FAQ

Mengapa perubahan UI saya hilang setelah saya regenerate aplikasi?

Mengedit file Vue yang dihasilkan berisiko karena regenerasi bisa menimpanya sepenuhnya. Bahkan jika perubahan Anda bertahan sekali, satu suntingan kecil di builder visual dapat membuat template dibuat ulang dan menghapus penyesuaian manual Anda.

Bagaimana saya bisa menyesuaikan UI yang dihasilkan tanpa kehilangan pekerjaan pada regenerasi berikutnya?

Letakkan semua kode Vue yang ditulis tangan di folder terpisah yang Anda miliki (misalnya direktori custom atau extensions) dan impor sebagai dependency. Perlakukan halaman yang dihasilkan sebagai output hanya-baca dan hubungkan ke komponen Anda hanya melalui antarmuka yang kecil dan stabil.

Apa itu komponen wrapper dan mengapa itu membantu pada layar yang dihasilkan?

Wrapper adalah komponen tipis yang Anda miliki yang berada di antara halaman yang dihasilkan dan widget Anda. Ia menerjemahkan bentuk data halaman menjadi props yang bersih dan mengubah event widget menjadi aksi halaman, sehingga jika data yang dihasilkan berubah nanti biasanya Anda hanya perlu memperbarui wrapper.

Apa cara paling aman merancang props dan event untuk widget yang dapat digunakan ulang?

Pertahankan kontrak kecil: beberapa props untuk data yang diperlukan widget, dan beberapa event untuk melaporkan niat pengguna. Pilih nilai sederhana dan objek polos yang Anda kontrol, tambahkan default, validasi input, dan gagal secara lembut dengan menampilkan keadaan kosong daripada melempar error.

Kapan saya harus emit `update:modelValue` vs `change` dari komponen kustom?

update:modelValue cocok ketika widget bertindak seperti kontrol form dan harus mendukung v-model. Gunakan change untuk aksi yang “dikonfirmasi” oleh pengguna, misalnya saat mereka menekan Simpan atau menyelesaikan pemilihan, sehingga parent tidak memproses setiap ketikan.

Bagaimana cara mencegah CSS widget saya merusak halaman yang dihasilkan lain?

Buat gaya widget ter-scope dan gunakan prefix kelas yang jelas agar halaman yang dihasilkan tidak secara tidak sengaja menimpa CSS Anda. Jika Anda perlu menyesuaikan dengan tema aplikasi, kirim token tema sebagai props (warna, spasi, ukuran font) daripada mengimpor atau bergantung pada gaya halaman.

Di mana sebaiknya logika bisnis berada jika saya menambahkan komponen UI kustom?

Secara default, simpan aturan bisnis di luar widget. Biarkan halaman atau backend yang menentukan izin, aturan validasi, dan perilaku simpan, sementara widget fokus pada render dan interaksi serta emit event seperti select, retry, atau approve.

Apa alasan paling umum komponen kustom rusak setelah regenerasi?

Hindari bergantung pada detail yang tidak stabil seperti jalur file yang dihasilkan, struktur DOM parent, atau bentuk objek state internal. Jika Anda memang memerlukannya, sembunyikan di dalam wrapper sehingga perubahan nama seperti user.name ke user.profile.name tidak memaksa Anda menulis ulang widget.

Apa yang harus saya uji sebelum dan setelah saya regenerate untuk menangkap masalah lebih awal?

Uji widget secara terpisah dengan props yang di-hardcode yang sesuai kontrak, termasuk nilai hilang dan malformed. Kemudian lakukan regenerasi dan verifikasi dua hal utama terlebih dahulu: apakah props yang sama masih dikirim, dan apakah event yang sama masih ditangani oleh halaman.

Kapan sebaiknya saya membangun widget Vue kustom daripada menggunakan blok UI bawaan?

Gunakan komponen kustom untuk hal-hal yang editor visual tidak bisa ekspresikan dengan baik, seperti grafik kompleks, pemilih peta, papan tanda tangan, atau perencana drag-and-drop. Jika kebutuhan bisa dipenuhi dengan menyesuaikan UI yang dihasilkan dan proses, biasanya itu lebih mudah dipelihara dalam jangka panjang.

Mudah untuk memulai
Ciptakan sesuatu yang menakjubkan

Eksperimen dengan AppMaster dengan paket gratis.
Saat Anda siap, Anda dapat memilih langganan yang tepat.

Memulai