Skip to content

useRoute() | Vue Router

useRoute() is a composition API function that provides access to the current route object. This function returns a reactive object containing information about the current route, including params, query, hash, and other route-specific data. 📍

📋 Function Signature

typescript
function useRoute(): RouteLocationNormalizedLoaded

🎯 Purpose and Functionality

The useRoute() function gives you access to the current active route information in a reactive way. Any changes to the route (like parameter changes or query updates) will trigger reactivity in your component.

Key Information Available:

  • Route Parameters - Dynamic segments like /user/:id
  • Query Parameters - URL query string values
  • Route Meta Information - Custom metadata attached to routes
  • Route Matching Details - Information about matched routes
  • Hash Fragment - URL hash value

📤 Return Value

Returns a reactive RouteLocationNormalizedLoaded object containing all information about the current route.

💡 Basic Usage Examples

Accessing Route Parameters

vue
<template>
  <div>
    <h1>User Profile: {{ userID }}</h1>
    <p>Query parameter: {{ searchQuery }}</p>
  </div>
</template>

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

const route = useRoute()

// Access route parameters reactively
const userID = computed(() => route.params.id)

// Access query parameters
const searchQuery = computed(() => route.query.q)
</script>

Route Information Display

vue
<template>
  <div>
    <p>Current path: {{ route.path }}</p>
    <p>Route name: {{ route.name }}</p>
    <p>Full path: {{ route.fullPath }}</p>
  </div>
</template>

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

const route = useRoute()
</script>

🔧 Advanced Usage Patterns

Watching Route Changes

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

const route = useRoute()

// Watch for specific parameter changes
watch(
  () => route.params.id,
  (newId, oldId) => {
    console.log('User ID changed:', oldId, '→', newId)
    loadUserData(newId)
  }
)

// Watch query parameters
watch(
  () => route.query.search,
  (newSearch) => {
    performSearch(newSearch)
  }
)

// Watch entire route object for any changes
watch(route, (newRoute, oldRoute) => {
  console.log('Route changed:', oldRoute.path, '→', newRoute.path)
})
</script>

Conditional Rendering Based on Route

vue
<template>
  <div>
    <div v-if="isAdminRoute" class="admin-toolbar">
      <AdminControls />
    </div>
    <main :class="{ 'admin-layout': isAdminRoute }">
      <RouterView />
    </main>
  </div>
</template>

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

const route = useRoute()

const isAdminRoute = computed(() => 
  route.path.startsWith('/admin')
)

const isEditMode = computed(() =>
  route.name === 'user-edit' || route.query.mode === 'edit'
)
</script>

Route Meta Information

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

const route = useRoute()

// Access route meta information
const requiresAuth = computed(() => 
  route.meta.requiresAuth === true
)

const pageTitle = computed(() =>
  route.meta.title || 'Default Title'
)

const breadcrumbs = computed(() =>
  route.meta.breadcrumbs || []
)
</script>

🚨 Important Considerations

Reactivity and Route Changes

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

const route = useRoute()

// ✅ Correct - using computed for reactivity
const userId = computed(() => route.params.id)

// ❌ Incorrect - losing reactivity
const userId = route.params.id // Not reactive!

// ✅ Correct - watch for changes
watch(() => route.params.id, (newId) => {
  // Handle ID change
})

// ✅ Correct - use in template directly (reactive)
// <div>{{ route.params.id }}</div>
</script>

Type Safety with TypeScript

vue
<script setup lang="ts">
import { useRoute } from 'vue-router'
import type { RouteParams } from 'vue-router'

const route = useRoute()

// Type-safe parameter access
const userId = computed(() => {
  // TypeScript will infer the correct type
  return route.params.id as string
})

// For complex params, you can use type assertions
interface UserRouteParams {
  id: string
  tab?: string
}

const userParams = computed(() => 
  route.params as UserRouteParams
)
</script>

📚 Route Object Properties

Core Properties

javascript
const route = useRoute()

// Basic route information
route.path        // Current path (e.g., "/user/123")
route.fullPath    // Full path with query and hash
route.name        // Route name if defined
route.hash        // URL hash fragment

// Parameters and query
route.params      // Object containing route parameters
route.query       // Object containing query parameters

// Meta information
route.meta        // Custom metadata attached to the route

// Matching information  
route.matched     // Array of matched route records

Practical Property Usage

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

const route = useRoute()

// Common computed properties based on route
const currentSection = computed(() => 
  route.path.split('/')[1] || 'home'
)

const hasQueryParams = computed(() =>
  Object.keys(route.query).length > 0
)

const isActiveRoute = computed(() => 
  route.name === 'target-route'
)

// Extract specific information
const pageNumber = computed(() => 
  parseInt(route.query.page) || 1
)

const sortOrder = computed(() =>
  route.query.sort || 'asc'
)
</script>

💡 Practical Examples

Dynamic Page Title

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

const route = useRoute()
const pageTitle = ref('')

watch(route, (newRoute) => {
  // Update page title based on route
  if (newRoute.meta.title) {
    pageTitle.value = newRoute.meta.title
    document.title = `${newRoute.meta.title} - My App`
  } else if (newRoute.name) {
    pageTitle.value = String(newRoute.name).replace(/-/g, ' ')
    document.title = pageTitle.value
  }
}, { immediate: true })
</script>

Search and Filter Implementation

vue
<template>
  <div>
    <input 
      v-model="searchTerm" 
      placeholder="Search..."
      @input="updateSearch"
    />
    <select v-model="selectedCategory" @change="updateCategory">
      <option value="">All Categories</option>
      <option v-for="cat in categories" :key="cat" :value="cat">
        {{ cat }}
      </option>
    </select>
  </div>
</template>

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

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

const searchTerm = ref(route.query.q || '')
const selectedCategory = ref(route.query.category || '')

// Update URL when filters change
const updateSearch = () => {
  router.push({
    query: { 
      ...route.query, 
      q: searchTerm.value || undefined 
    }
  })
}

const updateCategory = () => {
  router.push({
    query: { 
      ...route.query, 
      category: selectedCategory.value || undefined 
    }
  })
}

// Sync with route changes
watch(() => route.query.q, (newQ) => {
  searchTerm.value = newQ || ''
})

watch(() => route.query.category, (newCategory) => {
  selectedCategory.value = newCategory || ''
})
</script>

Authentication and Route Protection

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

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

onMounted(() => {
  // Check if current route requires authentication
  if (route.meta.requiresAuth && !isAuthenticated()) {
    // Redirect to login with return URL
    router.push({
      path: '/login',
      query: { redirect: route.fullPath }
    })
  }
  
  // Check user permissions for admin routes
  if (route.path.startsWith('/admin') && !isAdmin()) {
    router.replace('/access-denied')
  }
})
</script>

💡 Pro Tip: Use watch with immediate: true to handle both initial route values and subsequent changes in a single declaration.

🚀 Vue Router - 让前端路由变得简单而强大 | 构建现代化单页应用的最佳选择