📖 Vue.js Toàn tập - Vue Router
60 phút

Vue Router

Giới thiệu Vue Router

Vue Router là thư viện routing chính thức cho Vue.js.

Cài đặt và Cấu hình

Cài đặt

npm install vue-router@4

Cấu hình Router

// router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import About from '../views/About.vue'

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    component: About
  },
  {
    path: '/user/:id',
    name: 'User',
    component: () => import('../views/User.vue'),
    props: true
  }
]

const router = createRouter({
  history: createWebHistory(),
  routes
})

export default router

Kết nối với App

// main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

createApp(App).use(router).mount('#app')

Router Links và Views

RouterLink

<template>
  <nav>
    <router-link to="/">Home</router-link>
    <router-link to="/about">About</router-link>
    <router-link :to="{ name: 'User', params: { id: 123 } }">
      User Profile
    </router-link>
  </nav>
</template>

RouterView

<template>
  <div id="app">
    <nav>
      <!-- Navigation links -->
    </nav>
    <main>
      <router-view></router-view>
    </main>
  </div>
</template>

Route Parameters và Query

Dynamic Routes

<template>
  <div>
    <h1>User Profile</h1>
    <p>User ID: {{ $route.params.id }}</p>
    <p>Query: {{ $route.query.search }}</p>
  </div>
</template>

<script>
export default {
  created() {
    console.log('User ID:', this.$route.params.id)
  }
}
</script>

Composition API

<script setup>
import { useRoute, useRouter } from 'vue-router'

const route = useRoute()
const router = useRouter()

const userId = route.params.id
const searchQuery = route.query.search

const goToHome = () => {
  router.push('/')
}

const goToUser = (id) => {
  router.push({ name: 'User', params: { id } })
}
</script>

Navigation Guards

Global Guards

// router/index.js
router.beforeEach((to, from, next) => {
  const isAuthenticated = checkAuth()
  
  if (to.meta.requiresAuth && !isAuthenticated) {
    next('/login')
  } else {
    next()
  }
})

Route-specific Guards

{
  path: '/dashboard',
  component: Dashboard,
  beforeEnter: (to, from, next) => {
    if (!isAdmin()) {
      next('/unauthorized')
    } else {
      next()
    }
  }
}

Component Guards

<script>
export default {
  beforeRouteEnter(to, from, next) {
    // Không thể truy cập this
    next(vm => {
      // Có thể truy cập component instance qua vm
    })
  },
  
  beforeRouteUpdate(to, from, next) {
    // React to route changes
    this.userData = null
    this.fetchUserData(to.params.id)
    next()
  },
  
  beforeRouteLeave(to, from, next) {
    if (this.hasUnsavedChanges) {
      if (confirm('Bạn có chắc muốn rời đi? Thay đổi chưa được lưu sẽ mất.')) {
        next()
      } else {
        next(false)
      }
    } else {
      next()
    }
  }
}
</script>

Nested Routes

Cấu hình Nested Routes

{
  path: '/user/:id',
  component: User,
  children: [
    {
      path: '',
      component: UserProfile
    },
    {
      path: 'posts',
      component: UserPosts
    },
    {
      path: 'settings',
      component: UserSettings
    }
  ]
}

Sử dụng trong Template

<template>
  <div class="user">
    <nav class="user-nav">
      <router-link :to="`/user/${$route.params.id}`">Profile</router-link>
      <router-link :to="`/user/${$route.params.id}/posts`">Posts</router-link>
      <router-link :to="`/user/${$route.params.id}/settings`">Settings</router-link>
    </nav>
    
    <div class="user-content">
      <router-view></router-view>
    </div>
  </div>
</template>

📝 Bài tập (1)

  1. Tạo ứng dụng blog đa trang với routing

Tiến độ khóa học
Bài học "Vue Router" - Khóa học "Vue.js Toàn tập"