问题背景与描述

为了跟上时代的步伐,最近在开发一个vue3+vite+pinia的新项目开发过程中,体验了下vscode的copilot生成代码,不得不说效率真的牛逼!但同时,也会有一些小缺点小问题,需要我们去微调代码,就比如我今天遇到的坑。

我在某个页面组件中使用了useStore中的方法,为store中的某个状态初始化了数据,但跳转到另一个页面时,发现store中的状态被清空了。

解决方法

使用router.push方法替代原来的window.location.href做页面跳转即可解决

1
2
3
4
5
// 跳转到评分页面
const jumpToGrade = (item: Contestant) => {
// window.location.href = `/grade?id=${item.id}`
router.push({ path: '/grade', query: { id: item.id } })
}

问题排查过程

拷问了deepseek,豆包等AI,都说要对store进行持久化,但我觉得不太对,store的持久化主要是为了解决关闭标签页或者浏览器再打开应用时,还能保留还原历史数据的问题。使用store在一个单页应用内部做跳转,应该是不用做持久化的。

于是再次尝试了使用vscode内置的copilot,添加了store文件、做跳转的两个页面组件作为上下文,让其排查问题,好家伙,一下就排查出来了

原来是因为AI生成的代码里,跳转页面时使用的是window.location.href,而没有使用router.push()方法。

问题出现的原因

为什么使用window.location.href跳转页面时,会丢失store中的状态呢?GPT在回答中提到了SPA状态,SPA状态又是什么呢?

🔍 什么是 SPA 状态?

SPA(单页应用)状态指的是在不刷新整个页面的情况下,Vue/React 应用在内存中维护的所有数据状态,包括:

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
// 1. Vue 组件实例状态
const componentState = {
data: { count: 0, list: [] },
computed: {},
refs: {}
}

// 2. Pinia/Vuex 状态管理
const storeState = {
user: { name: 'John', isLogin: true },
cart: { items: [], total: 100 }
}

// 3. 路由状态
const routerState = {
currentRoute: '/home',
params: { id: 123 },
query: { search: 'hello' }
}

// 4. 事件监听器、定时器等
const sideEffects = {
eventListeners: [],
intervals: [],
timeouts: []
}

window.location.href的问题

传统跳转 vs SPA 路由跳转:

1
2
3
4
5
6
7
// ❌ 错误方式 - 破坏 SPA 状态
window.location.href = '/target-page'
// 相当于:浏览器完全刷新,重新加载所有资源

// ✅ 正确方式 - 保持 SPA 状态
router.push('/target-page')
// 只更新 URL,通过 JavaScript 动态渲染内容

总结

  • 在单页应用(SPA)中做页面跳转时,如果需要保留状态,需要使用router.push(),而不能使用window.location.href

拓展

在技术交流群里讨论这个问题时,有小伙伴了解到这个特性后,发现了window.location.href的妙用——在特定场景下需要彻底重置应用状态时,直接调用它可以强制刷新整个应用,从而免去繁琐的手动状态清理过程。