Gensics

Back to Home

Vue Router 4 และ Navigation Guards

Vue Developer19 ธันวาคม 2567Vue Routing
VueVue RouterNavigationSPA

Vue Router 4 มาพร้อมกับฟีเจอร์ใหม่และการปรับปรุงที่ทำให้การทำ routing ใน Vue 3 มีประสิทธิภาพมากขึ้น

การติดตั้งและตั้งค่า

npm install vue-router@4
// router/index.js import { createRouter, createWebHistory } from 'vue-router' import Home from '../views/Home.vue' import About from '../views/About.vue' import Login from '../views/Login.vue' const routes = [ { path: '/', name: 'Home', component: Home }, { path: '/about', name: 'About', component: About }, { path: '/login', name: 'Login', component: Login }, { path: '/dashboard', name: 'Dashboard', component: () => import('../views/Dashboard.vue'), meta: { requiresAuth: true } } ] const router = createRouter({ history: createWebHistory(), routes }) export default router

Global Guards

// Global before guard router.beforeEach((to, from, next) => { // Check if route requires authentication if (to.meta.requiresAuth) { const isAuthenticated = checkAuthStatus() if (!isAuthenticated) { next({ name: 'Login' }) return } } next() }) // Global after guard router.afterEach((to, from) => { // Update page title document.title = to.meta.title || 'My Vue App' // Track page views analytics.track('page_view', { path: to.path, name: to.name }) })

Route-specific Guards

const routes = [ { path: '/admin', component: AdminPanel, beforeEnter: (to, from, next) => { const user = getCurrentUser() if (!user || !user.isAdmin) { next({ name: 'Home' }) return } next() } } ]

Component Guards

<template> <div> <h1>Edit Post</h1> <form @submit.prevent="savePost"> <input v-model="post.title" placeholder="Title" /> <textarea v-model="post.content" placeholder="Content"></textarea> <button type="submit">Save</button> </form> </div> </template> <script> import { ref, onMounted } from 'vue' import { useRoute, useRouter } from 'vue-router' export default { setup() { const route = useRoute() const router = useRouter() const post = ref({ title: '', content: '' }) const hasUnsavedChanges = ref(false) onMounted(() => { loadPost(route.params.id) }) return { post, hasUnsavedChanges } }, beforeRouteLeave(to, from, next) { if (this.hasUnsavedChanges) { const answer = window.confirm( 'You have unsaved changes. Do you really want to leave?' ) if (!answer) { next(false) return } } next() } } </script>

Programmatic Navigation

<script> import { useRouter } from 'vue-router' export default { setup() { const router = useRouter() const goToAbout = () => { router.push('/about') } const goBack = () => { router.go(-1) } const goToUserProfile = (userId) => { router.push({ name: 'UserProfile', params: { id: userId }, query: { tab: 'profile' } }) } return { goToAbout, goBack, goToUserProfile } } } </script>

Dynamic Routes

const routes = [ { path: '/user/:id', name: 'UserProfile', component: UserProfile, props: true // Pass route params as props }, { path: '/blog/:slug', name: 'BlogPost', component: BlogPost, props: route => ({ slug: route.params.slug, category: route.query.category }) } ]

Route Meta Fields

const routes = [ { path: '/dashboard', component: Dashboard, meta: { requiresAuth: true, title: 'Dashboard', layout: 'AppLayout', breadcrumb: 'Dashboard' } } ] // ใช้งาน meta fields router.beforeEach((to) => { document.title = to.meta.title || 'Default Title' })

Error Handling

// Handle route errors router.onError((error) => { console.error('Route error:', error) if (error.message.includes('ChunkLoadError')) { window.location.reload() } }) // 404 route const routes = [ // ... other routes { path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFound } ]

Best Practices

  1. ใช้ Route Names - แทนที่จะใช้ hardcoded paths
  2. Lazy Loading - ใช้ dynamic imports สำหรับ components ขนาดใหญ่
  3. Meta Fields - เก็บข้อมูล routing ที่จำเป็น
  4. Error Boundaries - จัดการ errors ในการโหลด routes
  5. Loading States - แสดง loading indicators ระหว่างเปลี่ยน route

สรุป

Vue Router 4 ให้ความยืดหยุ่นในการจัดการ routing พร้อมกับ Navigation Guards ที่ช่วยให้เราควบคุมการนำทางได้อย่างมีประสิทธิภาพ