/src/assets/a.json
{
"data": [
{
"id":1,
"name": "hello",
"price": 20
},
{
"id":2,
"name": "vite",
"price": 30
},
{
"id":3,
"name": "pinia",
"price": 14
}
]
}
vscode插件: JSON to TS
json文件的ts代码如何生成:
1、选中json文件的内容
2、windows: ctrl+shift+alt+s
mac: control+shift+option+s
得到的内容:
![](https://i-blog.csdnimg.cn/blog_migrate/f6d679943b61e4f6f6844cca8df813c8.png)
/src/router/index.ts
import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router";
const routes: Array<RouteRecordRaw> = [
{
path: '/detail',
name: 'detail',
component: () => import('../components/Detail.vue')
}
];
const router = createRouter({
history: createWebHashHistory(),
routes
})
export default router;
1、query传参: url会带参数
/src/App.vue
<script setup lang="ts">
import { data } from "./assets/a.json";
import { useRouter } from "vue-router";
const router = useRouter();
type Datum = {
id: number;
name: string;
price: number;
}
const toAction = (item: Datum) => {
// query传参,和path搭配或者和name搭配,都可以,二选一
// 和path搭配
// router.push({
// path: '/detail',
// query: item
// });
// 和name搭配
router.push({
name: 'detail',
query: item
});
}
</script>
<template>
<div class="page">
<table cellspacing="0" border="1">
<thead>
<tr>
<th>姓名</th>
<th>年龄</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="item in data" :key="item.name">
<td>{{ item.name }}</td>
<td>{{ item.price }}元</td>
<td>
<button @click="toAction(item)">点击一下</button>
</td>
</tr>
</tbody>
</table>
</div>
<router-view></router-view>
</template>
<style>
html,
body,
#app,
.page {
width: 100%;
height: 100%;
}
.page {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
a {
margin-left: 20px;
}
td {
padding: 10px;
}
tbody tr td {
padding: 20px;
}
</style>
/src/components/Detail.vue
<script setup lang="ts">
import { useRoute, useRouter } from "vue-router";
// 当前路由的信息
const route = useRoute();
// vue路由对象
const router = useRouter();
</script>
<template>
<div class="page">
<h1>detail</h1>
<!-- router.back():🔙返回到上一页 -->
<button @click="router.back();">回退</button>
<!-- 通过route.query获取url的参数值,这种方式传参,刷新页面数据不会消失 -->
<!-- 举例url:http://localhost:5174/#/detail?id=1&name=hello&price=20 -->
<p>id:{{ route.query.id }}</p>
<p>姓名:{{ route.query.name }}</p>
<p>价格:{{ route.query.price }}</p>
</div>
</template>
<style scoped>
.page {
background: pink;
}
</style>
2、params传参+动态路由传参: url会带参数
/src/router/index.ts改造成下面这样:
{
// 动态路由
path: '/detail/:id',
name: 'detail',
component: () => import('../components/Detail.vue'),
}
/src/App.vue的<script>部分改造成下面这样:
<script setup lang="ts">
import { data } from "./assets/a.json";
import { useRouter } from "vue-router";
const router = useRouter();
type Datum = {
id: number;
name: string;
price: number;
}
const toAction = (item: Datum) => {
// params传参
router.push({
name: 'detail',
params: {
id: item.id
}
});
}
</script>
/src/components/Detail.vue改造成下面这样:
<script setup lang="ts">
import { data } from "../assets/a.json";
import { useRoute, useRouter } from "vue-router";
const route = useRoute();
const router = useRouter();
// 通过route.params.id找到data里符合的数据
const itemData = data.find(item => item.id === Number(route.params.id));
</script>
<template>
<div class="page">
<h1>detail</h1>
<button @click="router.back();">回退</button>
<!-- 得到的url是这样的,3是id值:http://localhost:5174/#/detail/3 -->
<!-- 刷新页面数据不会消失 -->
<!-- 加❓问号是因为会提示:ts对象可能为未定义ts(18048) -->
<p>id:{{ itemData?.id }}</p>
<p>姓名:{{ itemData?.name }}</p>
<p>价格:{{ itemData?.price }}</p>
</div>
</template>
<style scoped>
.page {
background: pink;
}
</style>
3、params传参: 如果没有和动态路由一起使用,详情页❌不可以通过route.params来获取参数值了
![](https://i-blog.csdnimg.cn/blog_migrate/e1bd95bcfad731b92c90eae05bd4c129.jpeg)
上图是Vue Router官网编程式导航的name和params的组合传参,如果没有和动态路由一起使用,详情页通过route.params来获取参数值,控制台会报警告⚠️,并且详情页得到的route.params是个空对象{}。
![](https://i-blog.csdnimg.cn/blog_migrate/8475666e0317116121b774807308b844.jpeg)
vue-router.js?v=5791c9af:42 [Vue Router warn]: Discarded invalid param(s) "id", "name", "price" when navigating. See https://github.com/vuejs/router/blob/main/packages/router/CHANGELOG.md#414-2022-08-22 for more details.
这是于2022年8月22日4.1.4版本的路由开始设置的,这样做的原因是“刷新页面获取到的参数会丢失”,详见https://github.com/vuejs/router/blob/main/packages/router/CHANGELOG.md#414-2022-08-22。
修改方案:见路由传参的其他方式
4、可以用History API的state传参: url不会带参数
/src/App.vue的<script>部分改造成下面这样:
<script setup lang="ts">
import { data } from "./assets/a.json";
import { useRouter } from "vue-router";
const router = useRouter();
type Datum = {
id: number;
name: string;
price: number;
}
const toAction = (item: Datum) => {
// history api的state传参
router.push({
name: 'detail',
state: item
});
}
</script>
/src/components/Detail.vue改造成下面这样:
<script setup lang="ts">
import { useRouter } from "vue-router";
const router = useRouter();
const state = history.state;
</script>
<template>
<div class="page">
<h1>detail</h1>
<button @click="router.back();">回退</button>
<!-- 通过History API的state获取参数值,刷新页面数据不会消失 -->
<p>id:{{ state.id }}</p>
<p>姓名:{{ state.name }}</p>
<p>价格:{{ state.price }}</p>
</div>
</template>
<style scoped>
.page {
background: pink;
}
</style>
5、将参数作为一个新属性传递给to.meta
这是已知的瞬间状态,并且由于它在导航守卫中,因此在重新加载页面时将被保留
router.beforeEach(async to => {
if (to.meta.shouldFetch) {
// name `data` whatever you want
to.meta.data = await fetchSomething()
}
})