Skip to content

RouteParams - 路由参数类型别名

RouteParams 是一个类型别名,定义了从动态路由路径中提取的参数的数据结构。它用于表示 URL 路径中的动态段(如 /user/:id 中的 id 参数)。🎯

📋 类型定义

typescript
type RouteParams = Record<string, RouteParamValue>

🎯 功能说明

这个类型就像是动态参数的"数据容器",提供:

  1. 类型安全 - 确保路径参数操作的类型正确性
  2. 数据结构统一 - 标准化动态参数的存储格式
  3. 多值支持 - 支持可重复的参数(如 /tags/vue/router

🔧 类型结构

基础结构

typescript
// RouteParams 的实际结构
interface RouteParams {
  [key: string]: RouteParamValue | RouteParamValue[]
}

参数值的类型

typescript
type RouteParamValue = string
type RouteParamValueRaw = RouteParamValue | number | null | undefined

💡 实际应用示例

访问路径参数

javascript
import { useRoute } from 'vue-router'

const route = useRoute()

// route.params 的类型就是 RouteParams
const params = route.params

// 访问单个参数(可能是 string 或 string[])
const userId = params.id
const category = params.category

类型安全的参数处理

typescript
// 安全的参数提取函数
function getRouteParam(
  params: RouteParams, 
  key: string
): string | null {
  const value = params[key]
  if (Array.isArray(value)) {
    return value[0] || null
  }
  return value || null
}

// 使用示例
const id = getRouteParam(route.params, 'id')
if (id) {
  fetchUserData(id)
}

处理数组参数

typescript
// 处理可重复的参数(如标签)
function getParamArray(
  params: RouteParams, 
  key: string
): string[] {
  const value = params[key]
  if (Array.isArray(value)) {
    return value
  } else if (value) {
    return [value]
  }
  return []
}

// 使用示例
const tags = getParamArray(route.params, 'tags')
// 对于路径: /tags/vue/router → tags = ['vue', 'router']

🎯 常见使用场景

用户详情页面

vue
<template>
  <div v-if="user">
    <h1>{{ user.name }}</h1>
    <p>用户 ID: {{ userId }}</p>
  </div>
  <div v-else>
    <p>加载中...</p>
  </div>
</template>

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

const route = useRoute()
const user = ref(null)
const userId = route.params.id

onMounted(async () => {
  if (userId) {
    user.value = await fetchUser(userId)
  }
})
</script>

分类和子分类

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

const route = useRoute()

// 处理嵌套分类参数
const mainCategory = route.params.category
const subCategory = route.params.subcategory

// 基于参数加载数据
const products = ref([])

watchEffect(async () => {
  if (mainCategory) {
    products.value = await fetchProducts({
      category: mainCategory,
      subcategory: subCategory
    })
  }
})
</script>

多标签筛选

vue
<template>
  <div>
    <h2>标签: {{ tags.join(', ') }}</h2>
    <div v-for="article in filteredArticles" :key="article.id">
      {{ article.title }}
    </div>
  </div>
</template>

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

const route = useRoute()
const allArticles = ref([])

// 获取标签数组
const tags = computed(() => {
  const value = route.params.tags
  return Array.isArray(value) ? value : (value ? [value] : [])
})

// 根据标签筛选文章
const filteredArticles = computed(() => {
  if (tags.value.length === 0) return allArticles.value
  
  return allArticles.value.filter(article =>
    tags.value.some(tag => article.tags.includes(tag))
  )
})
</script>

🔧 实用工具函数

参数验证和转换

typescript
// 验证数字参数
function getNumericParam(
  params: RouteParams, 
  key: string, 
  defaultValue: number = 0
): number {
  const value = params[key]
  const num = parseInt(Array.isArray(value) ? value[0] : value)
  return isNaN(num) ? defaultValue : num
}

// 使用示例
const page = getNumericParam(route.params, 'page', 1)
const limit = getNumericParam(route.params, 'limit', 10)

参数序列化(用于导航)

typescript
// 构建带参数的路由位置
function buildRouteWithParams(
  path: string, 
  params: Record<string, string | number>
): RouteLocationRaw {
  // 将参数转换为字符串
  const stringParams: RouteParams = {}
  Object.entries(params).forEach(([key, value]) => {
    stringParams[key] = value.toString()
  })
  
  return {
    path,
    params: stringParams
  }
}

// 使用示例
const nextPageRoute = buildRouteWithParams('/user/:id/profile', { id: 123 })
router.push(nextPageRoute)

参数合并和更新

typescript
// 合并现有参数和新参数
function mergeRouteParams(
  currentParams: RouteParams,
  newParams: Record<string, string | number>
): RouteParams {
  const merged = { ...currentParams }
  
  Object.entries(newParams).forEach(([key, value]) => {
    if (value === null || value === undefined) {
      delete merged[key]
    } else {
      merged[key] = value.toString()
    }
  })
  
  return merged
}

// 使用示例
const updatedParams = mergeRouteParams(route.params, { category: 'electronics' })
router.push({ params: updatedParams })

🎯 路由配置示例

定义动态路由

javascript
const routes = [
  {
    path: '/user/:id',
    component: UserDetail,
    props: true // 将 params 作为 props 传递
  },
  {
    path: '/category/:category/:subcategory?', // 可选参数
    component: CategoryPage
  },
  {
    path: '/tags/:tags+', // 一个或多个参数
    component: TagPage
  },
  {
    path: '/files/*', // 捕获所有路径
    component: FileBrowser
  }
]

在组件中使用参数

vue
<template>
  <UserDetail :id="parseInt($route.params.id)" />
</template>

<script>
export default {
  props: {
    id: {
      type: Number,
      required: true
    }
  }
}
</script>

🔗 相关类型

💡 专业建议:在处理路由参数时,始终进行类型验证和空值检查。对于数字参数,使用 parseInt() 进行转换并处理 NaN 情况。

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