query方式

login.vue:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<template>
<div>购物车</div>
<table cellspacing="0" class="table" border="1">
<thead>
<tr>
<th>品名</th>
<th>价格</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr :key="item.id" v-for="item in data">
<th>{{ item.name }}</th>
<th>{{ item.price }}</th>
<th><button @click="toDetail(item)">详情</button></th>
</tr>
</tbody>
</table>
</template>

<script setup lang="ts">
import { data } from "./list.json"
import { useRouter } from "vue-router"

const router = useRouter()

type Item = {
name: string
price: number
id: number
}

const toDetail = (item:Item)=> {
// query方式传参
router.push({
path: "/reg",
// 参数会被保存在url上,只能接收一个对象
query: item
})
}
</script>

<style scoped>
.table {
width: 400px;
border: 1px solid #ccc;
}
</style>

reg.vue:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<template>
<div>详情</div> <button @click="router.back">返回</button>
<div>
<!-- query方式接收参数 -->
<p>品名:{{ route.query.name }}</p>
<p>价格:{{ route.query.price }}</p>
<p>id:{{ route.query.id }}</p>
</div>
</template>

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

const route = useRoute()
const router = useRouter()
</script>

params方式

login.vue:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<template>
<div>购物车</div>
<table cellspacing="0" class="table" border="1">
<thead>
<tr>
<th>品名</th>
<th>价格</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr :key="item.id" v-for="item in data">
<th>{{ item.name }}</th>
<th>{{ item.price }}</th>
<th><button @click="toDetail(item)">详情</button></th>
</tr>
</tbody>
</table>
</template>

<script setup lang="ts">
import { data } from "./list.json"
import { useRouter } from "vue-router"

const router = useRouter()

type Item = {
name: string
price: number
id: number
}

const toDetail = (item:Item)=> {
// params方式传参
router.push({
// 不能使用path,必须使用name
name: "Reg",
// 未定义的params传递
params: item
})
}
</script>

<style scoped>
.table {
width: 400px;
border: 1px solid #ccc;
}
</style>

reg.vue:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<template>
<div>详情</div> <button @click="router.back">返回</button>
<div>
<!-- params方式接收参数 -->
<p>品名:{{ route.params.name }}</p>
<p>价格:{{ route.params.price }}</p>
<p>id:{{ route.params.id }}</p>
</div>
</template>

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

const route = useRoute()
const router = useRouter()
</script>

Vue-Router4.1.4移除了未定义的params传递,理由:这种传参方式是路由中的反模式,原因之一是重新加载页面会丢失参数

Vue给出的替代方案:

  • query传参
  • 将参数放在Pinia或VueX仓库里
  • 使用动态路由匹配
  • 传递state,在新页面使用History API接收参数
  • 使用meta原信息方式传递(更适用于路由守卫)

动态路由方式

/router/index.ts:

1
2
3
4
5
6
7
8
// ......省略
{
// 带:的路径是动态路由
path: "/reg/:id",
name: "Reg",
component: ()=> import("../components/reg.vue")
}
// 省略......

login.vue:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<template>
<div>购物车</div>
<table cellspacing="0" class="table" border="1">
<thead>
<tr>
<th>品名</th>
<th>价格</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr :key="item.id" v-for="item in data">
<th>{{ item.name }}</th>
<th>{{ item.price }}</th>
<th><button @click="toDetail(item)">详情</button></th>
</tr>
</tbody>
</table>
</template>

<script setup lang="ts">
import { data } from "./list.json"
import { useRouter } from "vue-router"

const router = useRouter()

type Item = {
name: string
price: number
id: number
}

const toDetail = (item:Item)=> {
// 动态路由方式传参
router.push({
name: "Reg",
// 在/router/index.ts定义了动态路由
params: {
id: item.id
}
})
}

</script>

<style scoped>
.table {
width: 400px;
border: 1px solid #ccc;
}
</style>

reg.vue:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<template>
<div>详情</div> <button @click="router.back">返回</button>
<div>
<!-- 动态路由匹配方式接收参数 -->
<p>品名:{{ item?.name }}</p>
<p>价格:{{ item?.price }}</p>
<p>id:{{ item?.id }}</p>
</div>
</template>

<script setup lang="ts">
import { data } from "./list.json"
import { useRoute, useRouter } from 'vue-router'

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

// 根据动态路由的参数id,从总数据中获取对应数据
const item = data.find(v=>v.id===Number(route.params.id))
</script>