RouteParams Type Alias | Vue Router
RouteParams is a type alias that defines the structure for route parameters extracted from URL paths. It provides type-safe access to dynamic route segments. 🔢
📋 Type Definition
typescript
type RouteParams = Record<string, RouteParamValue>🎯 Purpose and Usage
The RouteParams type alias represents the parameters extracted from route paths. It's used throughout Vue Router for type-safe parameter handling in routes, navigation, and component props.
Key Characteristics:
- ✅ Type Safety - Ensures proper parameter handling
- ✅ String Values - All parameters are converted to strings
- ✅ Flexible Structure - Supports optional and required parameters
- ✅ Route Matching - Used in route resolution and matching
🔍 Type Structure
Basic Parameter Structure
typescript
// For route path: "/user/:id"
const params: RouteParams = {
id: "123" // Always string values
}
// For route path: "/blog/:year/:month/:slug"
const params: RouteParams = {
year: "2023",
month: "12",
slug: "vue-router-guide"
}Parameter Value Types
All parameter values are strings, but the type alias supports the underlying RouteParamValue type which can be:
typescript
type RouteParamValue = string | number | null | undefined
// But in practice, they're always converted to strings💡 Practical Usage Examples
Accessing Route Parameters
vue
<script setup>
import { useRoute } from 'vue-router'
import { computed } from 'vue'
const route = useRoute()
// Basic parameter access
const userId = computed(() => route.params.id as string)
const postSlug = computed(() => route.params.slug as string)
// Multiple parameters
const blogParams = computed(() => ({
year: route.params.year as string,
month: route.params.month as string,
slug: route.params.slug as string
}))
// Parameter validation with fallbacks
const safeUserId = computed(() => {
const id = route.params.id
return id ? String(id) : 'unknown'
})
</script>Parameter-Based Logic
vue
<script setup>
import { useRoute } from 'vue-router'
import { computed, watch } from 'vue'
const route = useRoute()
// Watch for parameter changes
watch(() => route.params.id, (newId, oldId) => {
if (newId && newId !== oldId) {
loadUserData(newId as string)
}
})
// Conditional rendering based on parameters
const showEditButton = computed(() => {
return route.params.action === 'edit'
})
// Parameter validation
const isValidUser = computed(() => {
const id = route.params.id as string
return /^\d+$/.test(id) // Check if ID is numeric
})
</script>Navigation with Parameters
typescript
import type { RouteParams } from 'vue-router'
class NavigationService {
// Navigate to user profile
static navigateToUserProfile(userId: string): void {
const params: RouteParams = { id: userId }
router.push({
name: 'user-profile',
params
})
}
// Navigate to blog post
static navigateToBlogPost(
year: string,
month: string,
slug: string
): void {
const params: RouteParams = { year, month, slug }
router.push({
name: 'blog-post',
params
})
}
// Create parameterized URL
static createParameterizedPath(
pathTemplate: string,
params: RouteParams
): string {
let result = pathTemplate
for (const [key, value] of Object.entries(params)) {
result = result.replace(`:${key}`, value as string)
}
return result
}
}🔧 Advanced Patterns
Parameter Validation and Transformation
typescript
class ParameterProcessor {
// Validate and transform route parameters
static processUserParams(params: RouteParams): ProcessedUserParams {
const validation = this.validateUserParams(params)
if (!validation.isValid) {
throw new Error(`Invalid parameters: ${validation.errors.join(', ')}`)
}
return {
userId: parseInt(params.id as string),
action: params.action as string || 'view',
tab: params.tab as string || 'profile'
}
}
private static validateUserParams(params: RouteParams): ValidationResult {
const errors: string[] = []
// Validate required parameters
if (!params.id) {
errors.push('User ID is required')
} else if (!/^\d+$/.test(params.id as string)) {
errors.push('User ID must be numeric')
}
// Validate optional parameters
if (params.action && !['view', 'edit', 'delete'].includes(params.action as string)) {
errors.push('Invalid action parameter')
}
return { isValid: errors.length === 0, errors }
}
// Extract parameters from current route
static extractCurrentParams(): RouteParams {
return { ...router.currentRoute.value.params }
}
// Merge parameters with existing ones
static mergeParams(baseParams: RouteParams, additionalParams: RouteParams): RouteParams {
return { ...baseParams, ...additionalParams }
}
}Type-Safe Parameter Handling
typescript
// Define application-specific parameter types
interface UserRouteParams extends RouteParams {
id: string
action?: 'view' | 'edit' | 'delete'
tab?: string
}
interface BlogRouteParams extends RouteParams {
year: string
month: string
slug: string
}
// Type-safe parameter access
function getUserParams(params: RouteParams): UserRouteParams {
return {
id: params.id as string,
action: params.action as 'view' | 'edit' | 'delete',
tab: params.tab as string
}
}
function getBlogParams(params: RouteParams): BlogRouteParams {
return {
year: params.year as string,
month: params.month as string,
slug: params.slug as string
}
}Parameter-Based Routing Utilities
typescript
class ParameterRouting {
// Check if current route matches parameter pattern
static isMatchingRoute(pattern: string, params: RouteParams): boolean {
const currentRoute = router.currentRoute.value
return Object.keys(params).every(key =>
currentRoute.params[key] === params[key]
)
}
// Get parameter differences between routes
static getParameterChanges(
oldParams: RouteParams,
newParams: RouteParams
): string[] {
const changed: string[] = []
const allKeys = new Set([
...Object.keys(oldParams),
...Object.keys(newParams)
])
for (const key of allKeys) {
if (oldParams[key] !== newParams[key]) {
changed.push(key)
}
}
return changed
}
// Create parameterized navigation
static createParameterizedNavigation(
baseLocation: RouteLocationRaw,
params: RouteParams
): RouteLocationRaw {
if (typeof baseLocation === 'string') {
// Handle string paths
let path = baseLocation
for (const [key, value] of Object.entries(params)) {
path = path.replace(`:${key}`, value as string)
}
return path
} else if (baseLocation.path) {
// Handle path objects
let path = baseLocation.path
for (const [key, value] of Object.entries(params)) {
path = path.replace(`:${key}`, value as string)
}
return { ...baseLocation, path }
} else {
// Handle named routes
return {
...baseLocation,
params: { ...baseLocation.params, ...params }
}
}
}
}🚨 Important Considerations
Parameter Type Conversion
typescript
// Route parameters are always strings when accessed
const params = route.params
// ✅ Correct: Treat as strings
const userId = params.id as string
const pageNumber = parseInt(params.page as string)
// ❌ Incorrect: Assuming specific types
const userId = params.id as number // Wrong! params.id is string
// ✅ Better: Explicit conversion
const numericId = parseInt(params.id as string)
const booleanFlag = params.flag === 'true'Optional vs Required Parameters
typescript
// Route definition with different parameter types
const routes = [
{
path: '/user/:id', // Required parameter
component: UserProfile
},
{
path: '/blog/:year?/:month?', // Optional parameters
component: BlogArchive
},
{
path: '/search/:query*', // Repeatable parameter
component: SearchResults
}
]
// Parameter access patterns
const userParams = route.params // { id: string }
const blogParams = route.params // { year?: string, month?: string }
const searchParams = route.params // { query?: string[] }🔗 Related APIs
RouteLocation- Route location with parameters
📚 Best Practices
Parameter Validation Patterns
typescript
class ParameterValidator {
// Validate parameters with schema
static validateWithSchema(
params: RouteParams,
schema: ParameterSchema
): ValidationResult {
const errors: string[] = []
for (const [key, rule] of Object.entries(schema)) {
const value = params[key]
if (rule.required && !value) {
errors.push(`Parameter ${key} is required`)
continue
}
if (value && rule.pattern && !rule.pattern.test(value as string)) {
errors.push(`Parameter ${key} has invalid format`)
}
if (value && rule.allowedValues &&
!rule.allowedValues.includes(value as string)) {
errors.push(`Parameter ${key} has invalid value`)
}
}
return { isValid: errors.length === 0, errors }
}
// Common validation rules
static commonRules = {
id: { pattern: /^\d+$/, required: true },
slug: { pattern: /^[a-z0-9-]+$/ },
page: { pattern: /^\d+$/, allowedValues: null }
}
}Parameter Utilities
typescript
class ParameterUtils {
// Safe parameter access with defaults
static getParam(params: RouteParams, key: string, defaultValue: string = ''): string {
const value = params[key]
return value ? String(value) : defaultValue
}
// Get numeric parameter with validation
static getNumericParam(params: RouteParams, key: string, defaultValue: number = 0): number {
const value = params[key]
if (!value) return defaultValue
const numeric = parseInt(value as string, 10)
return isNaN(numeric) ? defaultValue : numeric
}
// Get boolean parameter
static getBooleanParam(params: RouteParams, key: string, defaultValue: boolean = false): boolean {
const value = params[key]
if (!value) return defaultValue
return value === 'true' || value === '1'
}
// Get array parameter
static getArrayParam(params: RouteParams, key: string): string[] {
const value = params[key]
if (!value) return []
return Array.isArray(value) ? value : [value as string]
}
}💡 Pro Tip: Always validate and sanitize route parameters before using them in your application. Use type guards and validation functions to ensure parameter safety and prevent runtime errors.