Nuxt项目双击路由跳转按钮时查询字符串(querystring)丢失如何解决
问题根因
- 代码笔误:
fetch方法中使用的this.$router.name是无效属性,正确的当前路由名称应该从this.$route.name获取,该错误会导致路由跳转目标异常,双击时两次快速跳转的冲突会放大该问题。 - 竞态冲突:双击按钮会触发两次连续的原生路由跳转,第一次跳转触发的
$fetch还未完成参数追加的router.push操作,第二次路由跳转就已经完成覆盖了路由状态,最终导致参数追加逻辑失效。 - 逻辑设计缺陷:在布局组件的
watch+fetch中处理参数追加,每次路由变化都需要触发二次router.push,本身就和原生路由跳转行为存在时序竞争,稳定性差。
方案一:使用Nuxt全局路由中间件(最稳定,无需修改原有业务代码)
该方案在路由跳转前就完成参数拼接,不会产生二次跳转冲突,兼容所有点击场景:
- 在项目
middleware目录下新建tokenPersist.js文件,代码如下:
export default function ({ route, redirect }) { // 优先从当前路由取token,取不到则读本地缓存 const accessToken = route.query.info || sessionStorage.getItem('access_info') if (accessToken) { // 缓存token防止刷新丢失 sessionStorage.setItem('access_info', accessToken) // 当前路由无token参数时,直接重定向到带参数的路由 if (!route.query.info) { return redirect({ path: route.path, query: { ...route.query, info: accessToken } }) } } }
- 在
nuxt.config.js中注册为全局中间件,所有路由跳转都会自动执行该逻辑:
export default { // 其余配置保持不变 router: { middleware: 'tokenPersist' } }
该方案无需修改原有default.vue和导航按钮代码,即可实现所有路由自动携带token参数。
方案二:修复原有布局组件代码
如果要保持现有逻辑写法,可通过修正笔误、加跳转锁解决双击问题:
修改default.vue的script部分代码如下:
import banner from '@/components/layouts/default/banner' export default { components: { banner }, data() { return { landingRoute: null, pushLock: false // 跳转锁,防止连续触发 } }, async fetch() { // 锁生效或无token时不执行逻辑 if (this.pushLock || !this.landingRoute) return if (this.isEmpty(this.$route.query)) { this.pushLock = true const landingKey = this.landingRoute // 修正路由名称取值错误 await this.$router.push({ name: this.$route.name, query: { info: landingKey } }) // 跳转完成300ms后解锁,避免双击重复触发 setTimeout(() => { this.pushLock = false }, 300) } }, watch: { '$route': { handler: '$fetch', immediate: true } }, mounted() { this.landingRoute = this.$route.query.info // 加本地缓存逻辑,刷新页面不会丢失token if (this.landingRoute) { sessionStorage.setItem('access_info', this.landingRoute) } else { this.landingRoute = sessionStorage.getItem('access_info') } }, methods: { isEmpty(json) { return Object.keys(json).length === 0 } } }
内容的提问来源于stack exchange,提问作者Jamie
相关产品推荐
相关产品推荐

