Vue Router: Navigasi Antar Halaman

Membuat aplikasi multi-halaman (SPA) dengan Vue Router: rute, RouterLink & RouterView, parameter dinamis, useRoute/useRouter, nested route, guard, dan lazy loading.

Part 21 dari 25 ± 55 menit Gratis

Single Page Application (SPA)

Pada situs tradisional, setiap klik tautan memuat halaman HTML baru dari server. Pada SPA, browser memuat aplikasi sekali, lalu JavaScript mengganti isi halaman tanpa reload — terasa seperti aplikasi desktop. Vue Router adalah pustaka resmi yang memetakan alamat URL ke komponen halaman.

npm install vue-router@4

Menyiapkan router

// src/router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import Beranda from '../views/Beranda.vue'
import Tentang from '../views/Tentang.vue'

const routes = [
  { path: '/', name: 'beranda', component: Beranda },
  { path: '/tentang', name: 'tentang', component: Tentang },
]

export default createRouter({
  history: createWebHistory(),
  routes,
})

// src/main.js
createApp(App).use(router).mount('#app')

Setiap rute minimal punya path dan component. name opsional tapi berguna untuk navigasi yang tahan perubahan URL.

Di latihan kursus ini kita memakai createMemoryHistory() karena halaman latihan tidak punya URL sendiri. Di proyek nyata gunakan createWebHistory() (URL bersih) atau createWebHashHistory() (URL berformat #/tentang, tanpa konfigurasi server).

RouterLink dan RouterView

<nav>
  <RouterLink to="/">Beranda</RouterLink>
  <RouterLink :to="{ name: 'tentang' }">Tentang</RouterLink>
</nav>

<RouterView />        <!-- tempat komponen halaman aktif dirender -->
  • RouterLink menghasilkan <a> tanpa reload halaman dan otomatis diberi class router-link-active / router-link-exact-active pada tautan aktif.
  • RouterView adalah "slot" halaman: isinya berganti sesuai URL.

Parameter dinamis

{ path: '/produk/:id', name: 'produk', component: DetailProduk }

<!-- DetailProduk.vue -->
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
</script>
<template>
  <h2>Produk #{{ route.params.id }}</h2>
</template>

Alamat /produk/7 menghasilkan route.params.id === '7' (selalu string). Query string (?q=vue) tersedia di route.query.q.

Perhatikan: berpindah dari /produk/1 ke /produk/2 memakai ulang komponen yang sama (tidak dibuat ulang). Pantau perubahannya dengan watch(() => route.params.id, ...).

Navigasi lewat kode

import { useRouter } from 'vue-router'
const router = useRouter()

router.push('/tentang')
router.push({ name: 'produk', params: { id: 7 } })
router.replace('/')        // tanpa menambah riwayat
router.back()              // seperti tombol back

Nested route (rute bersarang)

{
  path: '/akun',
  component: LayoutAkun,            // berisi <RouterView /> sendiri
  children: [
    { path: 'profil', component: Profil },     // /akun/profil
    { path: 'pesanan', component: Pesanan },   // /akun/pesanan
  ],
}

Navigation guard

router.beforeEach((to, from) => {
  if (to.meta.perluLogin && !sudahLogin()) {
    return { name: 'masuk' }       // alihkan
  }
})

{ path: '/dashboard', component: Dashboard, meta: { perluLogin: true } }

Lazy loading dan halaman 404

{ path: '/laporan', component: () => import('../views/Laporan.vue') }   // dimuat saat dibutuhkan

{ path: '/:pathMatch(.*)*', component: NotFound }                         // tangkap semua sisanya (taruh paling akhir)

Kesalahan umum

  • Memakai <a href="/tentang"> biasa sehingga halaman ter-reload; gunakan RouterLink.
  • Lupa <RouterView /> → URL berubah tapi tampilan kosong.
  • Menyimpan useRoute() di luar setup, atau menganggap params.id bertipe angka.
  • Deploy dengan createWebHistory() tanpa mengatur server agar mengembalikan index.html untuk semua path (error 404 saat refresh).

Praktikkan langsung, gratis

Tulis dan jalankan kode langsung di browser, dapatkan penilaian otomatis. Daftar gratis kapan saja untuk menyimpan progres dan meraih sertifikat.

Coba latihan sekarang, tanpa daftar
Bagikan: WhatsApp Facebook LinkedIn X