路由传参
有些时候我们希望在跳转到另一个页面的时候,携带一些参数过去,比如商品介绍页跳转到商品详情页,希望将商品的id携带过去到商品详情页用来查询对应商品id的详情信息。
路由携带参数通常被称作路由传参,路由传参常用的方式有如下3种:路由查询参数(query)、路由路径参数(params)、动态路由参数(params)。
路由传参一般在编程式导航中用的比较频繁,单单是进行路由跳转,不携带参数的话我们知道直接通过router.push(path)/router.replace(path)就可以实现。
携带参数进行路由跳转的话,就需要给router.push(object)/router.replace(object)传入一个对象参数。
-
如果是通过query传参,那么这个对象参数是这样的:
{ path: '/detail', query: {...} }。 -
获取query参数通过
route.query进行获取。 -
如果是通过params传参,那么这个对象参数是这样的:
{ path: '/detail', params: {...} }。 -
获取params参数通过
route.params进行获取。
我们可以看到,不管是query传参还是params传参,它们两个的值都是一个对象,而这个对象中的属性,就是你需要携带到另一个也页面的参数。
前期准备
data.json:
{
"data": [
{
"id": 1,
"name": "丝袜奶茶",
"price": 28
},
{
"id": 2,
"name": "芋泥波波",
"price": 30
},
{
"id": 3,
"name": "秋茶",
"price": 50
}
]
}
router/index.ts:
import { createRouter, createWebHistory } from 'vue-router'
const routes = [
{
path: '/', // router-link组件默认展示path为'/'对应的组件
component: () => import('@/views/list.vue'),
},
{
path: '/detail', // router-link组件默认展示path为'/'对应的组件
name: 'detail',
component: () => import('@/views/detail.vue'),
},
]
/** 创建vue-router实例对象 */
const router = createRouter({
history: createWebHistory(),
routes,
})
export default router
App.vue:
<template>
<router-view></router-view>
</template>
<script setup lang="ts"></script>
<style lang="scss" scoped>
a {
margin: 0 10px;
}
</style>
query传参
示例:
商品列表页-list.vue:
<template>
<div>
<table border cellspacing="0">
<thead>
<tr>
<th>商品id</th>
<th>商品名称</th>
<th>商品价格</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="product in data" :key="product.id">
<td>{{ product.id }}</td>
<td>{{ product.name }}</td>
<td>{{ product.price }}</td>
<td><button @click="toDetail(product)">详情</button></td>
</tr>
</tbody>
</table>
</div>
</template>
<script setup lang="ts">
import { useRouter } from 'vue-router'
import { data } from '@/assets/data.json'
const router = useRouter()
interface Product extends Record<string, any> {
id: number
name: string
price: number
}
const toDetail = (product: Product) => {
router.push({
path: '/detail',
query: product,
})
}
</script>
<style scoped>
table {
border-collapse: collapse;
}
</style>
商品详情页-detail:
<template>
<div>
<div>
<span>商品名称:</span>
<span>{{ name }}</span>
</div>
<div>
<span>商品价格:</span>
<span>{{ price }}</span>
</div>
<div>
<span>商品id:</span>
<span>{{ id }}</span>
</div>
</div>
</template>
<script setup lang="ts">
import { useRoute } from 'vue-router'
const route = useRoute()
const { id, name, price } = route.query
</script>
<style lang="scss" scoped></style>
可以发现,使用query进行传参,参数会暴露在url地址栏中。
params动态路由传参
使用params传参需要注意一点的是,不能通过path跳转,必须使用name进行跳转,否则获取不到参数。
router/index.ts:
{
path: '/detail/:id/:name/:price', // router-link组件默认展示path为'/'对应的组件
name: 'detail',
component: () => import('@/views/detail.vue'),
},
在路径中添加携带的参数: path: '/detail/:id/:name/:price'
list.vue:
const toDetail = (product: Product) => {
router.push({
name: 'detail',
params: product,
})
}
将path改为使用name
detail.vue
const { id, name, price } = route.params
route.query改为使用route.params获取传入的参数。
-
通过上面的例子我们发现,使用params动态路由传参的方式,我们需要提前向目标跳转路由的
path中声明添加需要携带的参数,声明的方式为: path: '路径/:携带的参数名'。 -
这样声明的params参数是必传的。也就是说跳转到目标路由的时候没有传入该参数,那么就会报错。
-
如果需要非必传的路径参数,可以在参数名称的后面加一个 ? 表示该路径参数为非必传参数,类似这样:path: '路径/:携带的参数名?'。
-
注意:我们在传参的时候,切记传入的参数名称一定要与路径中提前声明的参数名称保持一致。
-
可以发现,使用params进行传参,参数同样会暴露在url地址栏中,只不过query参数是跟在 ?, 而params路径参数不是跟在 ? 后面的。