eagleye

Quasar 路由 Props 传参:企业级应用指南

Quasar 路由 Props 传参:企业级应用指南

一、两种传参方式核心对比

特性

props: true

props: route => ({})

参数来源

仅路径参数 (params)

路径参数 + 查询参数 (query)

映射方式

自动映射同名 prop

手动自定义映射

类型转换

❌ 不支持

✅ 支持 (字符串→数字/布尔等)

默认值设置

❌ 不支持

✅ 支持

参数重命名

❌ 不支持

✅ 支持

企业级适用性

简单场景

复杂场景 (推荐)

二、props: true基础用法

1. 路由配置

// src/router/routes.ts

{

path: '/user/:userId',

component: () => import('pages/UserProfile.vue'),

props: true // 自动映射路径参数到组件 props

}

2. 组件接收

// pages/UserProfile.vue

const props = defineProps<{

userId: string // 与路由参数同名

}>()

// 使用

console.log(props.userId) // 直接访问路径参数

3. 适用场景

  • 单一ID参数传递(如/product/:id)
  • 参数名与组件prop名完全一致
  • 无需处理查询参数的简单页面

三、props: route => ({})高级用法

1. 基础多参数映射

// 路由配置

{

path: '/profile/:userId',

component: UserProfile,

props: route => ({

// 路径参数

userId: route.params.userId,

// 查询参数 + 默认值

viewMode: route.query.mode || 'standard',

// 类型转换

isEditing: route.query.edit === 'true',

// 复杂计算

accessLevel: getUserAccess(route.params.userId)

})

}

// 组件接收

const props = defineProps<{

userId: string

viewMode: 'standard' | 'compact'

isEditing: boolean

accessLevel: 'read' | 'write' | 'admin'

}>()

2. 企业级参数处理封装

// utils/routeParams.ts

export function processParams(route: RouteLocationNormalized) {

return {

// 参数验证

projectId: validateProjectId(route.params.projectId),

// 类型转换 + 默认值

page: parseInt(route.query.page as string) || 1,

// 枚举验证

sortBy: ['name', 'date', 'size'].includes(route.query.sort as string)

? route.query.sort

: 'date',

// 复杂对象解析

filters: route.query.filters

? JSON.parse(decodeURIComponent(route.query.filters as string))

: {}

}

}

// 路由配置中使用

{

path: '/projects/:projectId',

component: ProjectDashboard,

props: route => processParams(route)

}

四、企业级最佳实践

1. 参数验证策略

// 验证函数示例

function validateUserId(userId: unknown): string {

if (typeof userId !== 'string' || !/^[A-Z0-9]{32}$/.test(userId)) {

throw new Error(`Invalid user ID: ${userId}`)

}

return userId

}

// 路由配置中集成

props: route => ({

userId: validateUserId(route.params.userId),

// 其他参数...

})

2. 多场景传参方案

场景A:电商产品列表

{

path: '/products',

component: ProductList,

props: route => ({

category: route.query.category || 'all',

sort: {

by: route.query.sortBy || 'price',

order: route.query.order === 'desc' ? 'desc' : 'asc'

},

pagination: {

page: parseInt(route.query.page as string) || 1,

limit: parseInt(route.query.limit as string) || 20

}

})

}

场景B:数据可视化仪表板

{

path: '/analytics/:dashboardId',

component: AnalyticsDashboard,

props: route => ({

dashboardId: route.params.dashboardId,

dateRange: {

start: route.query.startDate as string,

end: route.query.endDate as string

},

metrics: route.query.metrics

? (route.query.metrics as string).split(',')

: ['revenue', 'users']

})

}

3. 类型安全增强

// types/route.ts

export interface ProductListProps {

category: string

sort: {

by: 'price' | 'rating' | 'date'

order: 'asc' | 'desc'

}

pagination: {

page: number

limit: number

}

}

// 组件中使用

import type { ProductListProps } from '@/types/route'

const props = defineProps<ProductListProps>()

五、常见问题解决方案

1. 参数刷新丢失

问题:页面刷新后查询参数丢失

方案:通过路由props注入而非直接读取$route

// ✅ 正确:通过props接收

const props = defineProps<{ tab: string }>()

// ❌ 错误:直接依赖$route

const tab = ref(route.query.tab) // 刷新后需手动同步

2. 复杂对象传递

方案:使用JSON序列化+URL编码

// 传递端

const filters = { price: [100, 500], tags: ['new'] }

router.push({

path: '/products',

query: { filters: encodeURIComponent(JSON.stringify(filters)) }

})

// 接收端

props: route => ({

filters: route.query.filters

? JSON.parse(decodeURIComponent(route.query.filters as string))

: {}

})

3. 参数变更响应

// 监听props变化

watch(

() => props.userId,

(newId) => {

fetchUserData(newId) // 参数变化时重新加载数据

},

{ immediate: true } // 初始加载时执行

)

六、企业级架构建议

1. 参数处理分层

路由层 → 参数验证层 → 组件层

↓ ↓ ↓

路径/查询 → 验证/转换 → 类型化props

2. 工具函数封装

// composables/useRouteParams.ts

export function useRouteParams() {

const router = useRouter()

return {

// 安全更新查询参数

updateQuery: (params: Record<string, any>) => {

router.push({

...router.currentRoute.value,

query: { ...router.currentRoute.value.query, ...params }

})

}

}

}

3. 性能优化

  • 避免在props函数中执行复杂计算
  • 对大型数据集使用shallowRef
  • 使用Object.freeze()冻结静态默认值

七、最佳实践总结

1. 优先选择函数形式props: route => ({})提供完整控制能力

2. 全面参数验证:对所有外部输入进行类型和格式校验

3. 类型系统集成:使用TypeScript接口定义props结构

4. 默认值全覆盖:为所有可选参数提供合理默认值

5. 避免直接依赖$route:通过props注入实现组件解耦

6. 复杂逻辑封装:将参数处理逻辑提取为独立工具函数

通过以上规范,可构建类型安全、可维护、抗异常的企业级路由参数系统,同时兼顾开发效率与代码质量。

 

posted on 2025-08-06 17:33  GoGrid  阅读(10)  评论(0)    收藏  举报

导航