问题
再写 vue3 + ts + vite 项目的时候用到了路由,但是实际使用的时候出现了问题,把问题记录一下
vue-router@3 路由传参
1 传参方式 -- query
特点: 参数显示在路径上,刷新保留数据
A.vue
methods{
toPush(item){
this.$router.push({
path: '/B',
query:{
data
}
})
}
}
B
// 通过 this.$route.query 可以获取到数据
this.$route.query.data
2 传参方式 --- params
- 路径显示参数
特点: 路径显示参数, 刷新保留数据, 需在路由配置匹配
router.js
{
path: '/B/:id',
name:' B',
component:-----
}
A.vue
注意需指定name ---> 路由名称
methods{
toPush(item){
this.$router.push({
name: 'B',
query:{
id: 1234
}
})
}
}
获取
this.$route.params
- 路径不显示参数
特点: 参数不显示在路径上,刷新不保留数据
router.ts
{
path: '/B',
name:' B',
component:-----
}
A.vue
methods{
toPush(item){
this.$router.push({
name: 'B',
query:{
id: 1234
}
})
}
}
获取方式无太大区别
vue-router@4 路由传参
其实和三版本区别不大
这里写一个简单示例(将home路由下的数据传递给like路由)
query 方式
home路由组件
<script lang='ts' setup>
import { reactive } from 'vue';
// 使用路由
import { useRouter } from 'vue-router';
const router = useRouter();
// 接口参数说明
/*
@ interface MyList params {
id : 唯一标识
city : 城市
climate : 气候
more : 更多
}
*/
interface MyList {
readonly id: number | string;
city: string;
climate: string;
more?: string[]
}
// 这里定义默认数据
let objLIst = reactive<MyList[]>([
{ id: 0, city: '北京', climate: '晴朗' },
{ id: 1, city: '上海', climate: '多云' },
{ id: 3, city: '南宁', climate: '小雨' }])
// 跳转方法
const toPush = (item: MyList): void => {
}
</script>
<template>
<h1>home</h1>
<h3>query传递参数</h3>
<button @click="toPush(item)" v-for="item in objLIst" :key="item.id">传递给like路由的数据(query){{item.id}}</button>
</template>
home页面
like
<script lang='ts' setup>
import { toRefs, reactive, ref } from 'vue';
import { useRoute } from 'vue-router'
// 获取路由参数
const route = useRoute();
let data = reactive(JSON.parse((route.query.res)!.toString()))
let { id, city, climate } = toRefs(data)
</script>
<template>
<h1>like</h1>
<hr>
<h3>query</h3>
<ul>
<li>id:{{id}}</li>
<li>city:{{city}}</li>
<li>climate:{{climate}} </li>
</ul>
</template>
router.ts
const stateRouterLists: Array<RouteRecordRaw> = [{
path: '/',
name: 'index',
component: () => import('@/views/home/index.vue')
}, {
path: '/like',
name: 'like',
component: () => import('@/views/like/index.vue')
}, {
path: '/login',
name: 'login',
component: () => import('@/views/login/index.vue')
}, {
path: '/error',
name: '404',
component: () => import('@/views/login/index.vue')
}]
访问可以拿到数据, 路径上也有参数, 刷新不丢失数据
http://127.0.0.1:5173/#/like?res={"id":0,"city":"北京","climate":"晴朗"}
params 显示路径
router.ts
{
path: '/',
name: 'index',
component: () => import('@/views/home/index.vue')
}, {
path: '/like/:id',
name: 'like',
component: () => import('@/views/like/index.vue')
}
home路由组件
<script lang='ts' setup>
import { reactive } from 'vue';
import { useRouter } from 'vue-router';
const router = useRouter();
/*
@ interface MyList params {
id : 唯一标识
city : 城市
climate : 气候
more : 更多
}
*/
interface MyList {
readonly id: number | string;
city: string;
climate: string;
more?: string[]
}
let objLIst = reactive<MyList[]>([
{ id: 0, city: '北京', climate: '晴朗' },
{ id: 1, city: '上海', climate: '多云' },
{ id: 3, city: '南宁', climate: '小雨' }])
const toPush1 = (id: number | string): void => {
router.push({
name: 'like',
params: {
id
}
})
}
</script>
<template>
<h1>home</h1>
<h3>params传递参数</h3>
<button @click="toPush1(item.id)" v-for="item in objLIst" :key="item.id">传递给like路由的数据(params){{item.id}}</button>
</template>
like
<script lang='ts' setup>
import { toRefs, reactive, ref } from 'vue';
import { useRoute } from 'vue-router'
const route = useRoute();
let data1 = ref(route.params.id);
// 假设是vuex中的数据
interface MyList {
readonly id: number | string;/ city: string;
climate: string;
more?: string[]
}
let objLIst = reactive<MyList[]>([
{ id: 0, city: '北京', climate: '晴朗' },
{ id: 1, city: '上海', climate: '多云' },
{ id: 3, city: '南宁', climate: '小雨' }])
let { id, city, climate } = toRefs(objLIst.find((item) => data1.value == item.id) || { id: -1, city: '', climate: '' })
</script>
<template>
<h1>like</h1>
<h3>params</h3>
<ul>
<li>id:{{id}}</li>
<li>city:{{city}}</li>
<li>climate:{{climate}} </li>
</ul>
</template>
访问可以拿到数据, 路径上也有参数, 刷新不丢失数据
http://127.0.0.1:5173/#/like/0
关键的第三种方式
在实际使用中我发现route.params
拿不到数据
并且浏览器vue报了一个警告
[Vue Router warn]: Discarded invalid param(s) "id" when navigating. See https://github.com/vuejs/router/blob/main/packages/router/CHANGELOG.md#414-2022-08-22 for more details.
进入链接
大概就是说,这种用法如果没有在路由表上面声明动态参数,将会造成刷新后参数丢失。
在 v4.1.4
版本的更新中,增加了删除未使用的参数这个功能。所以会提示你 Discarded invalid param(s) "name", "price", "id"
(丢弃无效的参数 "name"
, "price"
, "id"
)。
如果想要解决,可以在路由表中声明你用到的这些参数,或者使用 query
的形式来传递参数。也可以用 vuex
之类的状态管理来暂存。`