Vue · Bab 6
Vue Router
Membuat aplikasi satu halaman dengan banyak alamat memakai Vue Router, rute bernama dan param, navigasi lewat kode, halaman 404, dan fokus yang pindah ke judul setiap kali rute berganti.
Aplikasi perpustakaan butuh lebih dari satu “halaman”: daftar koleksi, detail satu buku, daftar anggota. Di frontend terpisah, semua halaman itu tetap satu dokumen HTML; yang berganti hanya komponen yang tampil. Vue Router menghubungkan alamat (URL) dengan komponen, sehingga setiap halaman punya alamat sendiri yang bisa disalin, dibagikan, dan dibuka lagi.
6.1 SPA dan URL
Aplikasi seperti ini disebut SPA (single-page application). Berpindah halaman tidak meminta dokumen baru ke server; JavaScript mengganti isi halaman dan memperbarui alamat. Hasilnya cepat, tetapi tiga hal yang dulu gratis kini harus dijaga router:
- alamat di bilah browser ikut berubah;
- tombol Kembali browser kembali ke halaman sebelumnya;
- membuka alamat langsung (misalnya dari tautan yang dibagikan) menampilkan halaman yang benar.
6.2 Rute Pertama
Router dibuat dengan createRouter dan sebuah history. Bab ini memakai createWebHashHistory(): alamat halaman ditulis setelah tanda #, misalnya #/anggota.
🧪 Coba ubah: tambahkan rute /denda dengan komponen yang menulis “Denda 1000 rupiah per hari terlambat”, lalu tautannya di menu.
Belum ada output.
<router-link to="…">dirender menjadi<a>biasa, tetapi kliknya ditangani router tanpa memuat ulang halaman.<router-view>adalah tempat komponen rute yang aktif ditampilkan.
6.3 Param dan Rute Bernama
Halaman detail memakai param: /buku/:id cocok dengan /buku/1, /buku/2, dan seterusnya. Di komponen, nilainya dibaca dari useRoute().params.id (selalu string).
Rute boleh diberi nama. Tautan ke rute bernama tidak merangkai URL sendiri: :to="{ name: 'buku', params: { id: b.id } }". Bila path-nya kelak diubah menjadi /koleksi/:id, semua tautan tetap benar.
🧪 Coba ubah: hapus Number(...) dan lihat detail tidak ditemukan lagi, karena '2' === 2 bernilai false.
Belum ada output.
6.4 Komponen yang Dipakai Ulang
Berpindah dari /buku/1 ke /buku/2 memakai komponen yang sama. Vue tidak membuangnya, hanya mengganti param, sehingga onMounted tidak terpanggil lagi. Bila data diambil di onMounted, halaman tetap menampilkan buku pertama.
Solusinya: pantau param dengan watch, dan { immediate: true } agar pengambilan pertama juga terjadi:
const route = useRoute();
const buku = ref(null);
watch(
() => route.params.id,
async (id) => {
buku.value = null;
buku.value = (await http.get('/buku/' + id)).data.data;
},
{ immediate: true },
);
Dengan computed seperti contoh 6.3 masalah ini tidak muncul, karena computed membaca route.params.id setiap kali dihitung. watch dibutuhkan saat perubahan param harus memicu aksi, misalnya request.
6.5 Navigasi Lewat Kode
Tidak semua perpindahan berasal dari klik tautan. Setelah petugas selesai mencatat peminjaman, aplikasi membawanya kembali ke daftar:
const router = useRouter();
async function selesaiPinjam() {
await catatPeminjaman();
router.push({ name: 'daftar' });
}
router.push menambah riwayat (tombol Kembali kembali ke halaman form); router.replace mengganti entri terakhir.
6.6 Halaman 404
Alamat yang tidak cocok dengan rute mana pun menampilkan <router-view> kosong. Tambahkan rute penampung paling akhir:
{ path: '/:pathMatch(.*)*', component: TidakDitemukan }
pathMatch(.*)* cocok dengan path apa saja. Karena router memilih rute paling spesifik, rute ini hanya dipakai bila tidak ada rute lain yang cocok.
6.7 Fokus Setelah Pindah Rute
Saat dokumen baru dimuat, pembaca layar mengumumkan judul halaman. Di SPA tidak ada dokumen baru, jadi pengguna pembaca layar tidak tahu bahwa isinya berganti. Pindahkan fokus ke judul halaman baru setelah setiap perpindahan:
🧪 Coba ubah: hapus tabindex="-1" dari salah satu h1. Judul biasa tidak bisa difokuskan, sehingga fokus tidak berpindah.
Belum ada output.
tabindex="-1" membuat judul bisa difokuskan lewat kode tanpa ikut urutan tombol Tab. nextTick menunggu komponen rute baru selesai dirender, karena afterEach terpanggil sebelum DOM diperbarui.
6.8 Hash atau History?
createWebHashHistory() | createWebHistory() | |
|---|---|---|
| Bentuk alamat | /#/buku/2 | /buku/2 |
| Aturan server | tidak perlu | server harus mengembalikan index.html untuk semua path |
| Cocok untuk | hosting statis, preview lab | aplikasi produksi dengan server yang bisa diatur |
Bagian setelah # tidak pernah dikirim ke server, jadi hosting statis apa pun cukup. Dengan createWebHistory, membuka /buku/2 langsung meminta berkas /buku/2 ke server; tanpa aturan fallback, hasilnya 404. Bab 10 membahas aturan itu saat aplikasimu dipublikasikan.
Rangkuman
createRouter({ history: createWebHashHistory(), routes }), laluapp.use(router).<router-link>untuk tautan,<router-view>untuk tempat halaman.- Param
/buku/:iddibaca denganuseRoute().params.id(string); rute bernama untuk tautan. - Komponen dipakai ulang saat param berubah:
watchdengan{ immediate: true }. router.pushuntuk navigasi lewat kode, rute/:pathMatch(.*)*untuk 404, fokus keh1setelahafterEach.
Berikutnya: Lab bab 6 memasang router di etalase Smart Retail: katalog, detail produk, 404, dan fokus.