问题背景
在开发中,经常会遇到需要使用路由传参的形式传递参数。路由传参总共有两种方法:params和query,而使用params传参在刷新页面时数据会丢失,因此对于一些场景,我们更多的使用query传参的方式。
问题引出
今天小小白在项目中遇到这样的问题,使用query路由传参的方式传了一个对象
// 参数定义
testParams: {
a: 1,
b: 2
}
// 路由跳转
this.$router.push({ path: "/test", query: { testParams: this.testParams } });
首次跳转的时候数据获取没有问题,但是当刷新页面之后,神奇的事情发生了,页面数据不见了。于是小小白在跳转目标页面做了一个路由数据获取并打印,打印结果如下:
首次进入
可以看到,控制台输出数据正常打印。
刷新页面
神奇的事情发生了,原本的对象参数变成了Object。
看到这里,小小白顿时明白发生了什么,原来在我们使用路由传递参数的时候,参数会被转换成字符串类型(对于对象而言,也就是我们看到的[object Object])并附加到URL的查询参数中,因此当我们刷新页面之后,再次从路由中获取到的对象参数就变成了[object Object]。
那为什么首次跳转的时候可以获取到正常的值呢?
这是因为在我们进行路由跳转时,Vue Router 会在内存中保留这些对象原始的 JavaScript 对象形式,直到页面刷新或重新加载。
因此我们首次跳转进页面时,获取的数据实则是存在内存中的实际对象值,而刷新页面之后,获取到的值就变成了URL的查询参数中已经转换过的[object Object]了。
怎么解决
既然已经知道问题出在哪里,那就好解决了。
既然路由参数会转换成字符串进行传递,那么只需要在传递之前手动将要传递的对象转换为Json字符串,然后在目标页面获取解析回对象,问题就完美解决了。上代码!!!
// 原页面将数据转换为JSON串进行传递
const testParams = JSON.stringify(this.testParams);
this.$router.push({ path: "/contestSystem/enrollDetails", query: { testParams: testParams } });
// 目标页面获取时将数据转换回对象格式
const testParams = JSON.parse(this.$route.query.testParams)
通过上述修改后,不论是首次跳转进入页面还是刷新之后的页面,都可以完美的获取到数据啦。
美中不足
使用路由query传递参数确实很方便,但随之而来的也有一些问题。
第一:URL过长
如果传递的是大型对象,序列化后的 JSON 字符串可能会超出浏览器的 URL 长度限制,导致无法正常传递。
第二:参数暴露
URL 参数是公开的,任何人都可以查看、修改和共享。因此,敏感信息不应通过这种方式传递。
第三:性能影响
对象序列化为字符串和反序列化回对象会带来一定的性能开销,特别是对于大型对象或频繁的导航操作。
因此,如果对以上几点有考量的设计方案,建议采取其他方法进行参数传递,比如使用Vuex等进行数据管理,本文对该技术不做讲解,有兴趣的小伙伴自行查阅资料。
bye~~