Pinia调用state时store未完成安装 首次请求jwt授权头为undefined
问题产生原因
这个问题和Pinia store挂载顺序无关,是两处代码错误叠加导致的:
- 第一处是嵌套store调用方式错误:你在
dataStore的getAccounts方法中写了const user = useUserStore,没有加括号执行useUserStore(),这行代码只是把Pinia store的定义函数赋值给了user变量,根本没有获取到实际的响应式store实例,直接从函数对象上取jwt属性自然会拿到undefined。 - 第二处是登录流程异步时序错误:你在登录逻辑中调用
userStore.getJWT()时没有加await等待执行完成,如果getJWT是异步拉取token的方法,代码会直接触发路由跳转,不会等jwt写入store。跳转到数据页后onMounted钩子会立刻触发getAccounts请求,这时候jwt还没返回存入store,自然读不到有效值。
后续导航到其他页面时能正常读取,是因为此时jwt早已经异步拉取完成存入了Pinia,且相关页面正确调用useUserStore()后,响应式状态已经完成初始化。
另外你直接修改axios实例全局defaults.headers的写法有全局副作用,多请求并发、多账号切换时很容易出现header串值的问题。
正确修复方案
按以下规则修改即可彻底解决问题:
- 修正嵌套store的调用方式,必须加括号执行composable拿到实际store实例
- 给登录流程中的
getJWT调用加await,等鉴权信息完全写入store后再跳转路由 - 替换全局修改axios默认头的写法,避免全局副作用
修正后的登录提交代码
const submitlogin = async () => { try { const response = await postData.post('/user/a/login', { email: form.email, password: form.password, }) if (response) { userStore.loggedIn = true // 等待jwt拉取、写入store完成 await userStore.getJWT() // 鉴权信息就绪后再跳转 router.push({ name: 'operation', params: { sens: 'depense', quand: 'maintenant' }, }) } } catch (error) { console.log(error) } }
修正后的dataStore代码
// dataStore import { defineStore } from 'pinia' import { useUserStore } from '@/stores/userStore.js' export const useDataStore = defineStore('data', { // 其他state、getters配置省略 actions: { async getAccounts(id, month, year) { // 必须加()调用,拿到实际的store实例 const user = useUserStore() // 直接在请求配置中传入header,不要修改全局defaults const response = await getData.get(`/use/b/comptes/${id}/${month}/${year}`, { headers: { '__authorization__': user.jwt } }) // 后续响应处理逻辑 } } })
可选优化:统一用axios拦截器注入token
你可以直接在axios实例的配置文件中添加请求拦截器,不用每个接口单独传header,彻底避免全局配置的副作用:
// axios实例初始化文件 getData.interceptors.request.use((config) => { // 拦截器触发时再获取最新的store状态 const userStore = useUserStore() if (userStore.jwt) { config.headers['__authorization__'] = userStore.jwt } return config })
加了拦截器之后,所有通过getData发出的请求都会自动带上最新的jwt,不需要在每个action里手动设置header。
内容的提问来源于stack exchange,提问作者thiebo
相关产品推荐
相关产品推荐

