You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3.2 <script setup>中API服务调用Pinia store报错求助

解决Vue 3.2中API服务访问Pinia Store的初始化错误

问题描述

使用Vue 3.2的<script setup>语法时,在API服务中访问Pinia Store出现以下错误:

Uncaught ReferenceError: Cannot access 'store' before initialization at api.js?:9:1

原始代码

src/services/api.js(首次尝试):

import axios from 'axios';
import store from '../stores/index';

const api = axios.create({ baseURL: import.meta.env.VITE_APP_API_URL });

if (store) {
  const { token } = store;

  if (token) {
    api.defaults.headers.Authorization = `Bearer ${token}`;
  }
}
console.log(api);

export default api;

src/stores/index.ts:

import { defineStore } from 'pinia'
import Project from '../models/Project';
import { grantAuthSshd, revokeAuth, parseJwt } from '../services/auth';

const initialUser = JSON.parse(sessionStorage.getItem('Orcamento:token') || '{}');

const useProject = defineStore('project-store', {
  state: () => ({
    loading: false as boolean,
  }),
  actions: {
    loadingDataTable(status: ((status: boolean) => void) & boolean) {
      this.loadingDataTable = status;
    },
  }
});

拦截器尝试仍报错

import axios from 'axios';
import useProject from '../stores/index';

const api = axios.create({ baseURL: import.meta.env.VITE_APP_API_URL });

api.interceptors.request.use(
  (config) => {
    const { token } = store;
    if ({token}) {
      api.config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);
  
const store = useProject();

export default api;

错误原因分析

  1. Store导出错误:src/stores/index.ts中导出的是defineStore返回的创建Store的函数,而非实例化后的Store对象,直接import并当作实例使用会出错。
  2. 提前引用变量:拦截器尝试中,回调函数里引用了尚未声明的store变量,导致初始化顺序错误。
  3. Store缺少token字段:原始Store的state中没有定义token,无法获取令牌值。
  4. 拦截器修改对象错误:尝试修改api.config.headers而非请求传入的config.headers,无法正确设置请求头。

解决方案

1. 修正Store定义与导出

完善Store的state字段,并导出创建Store的函数:

// src/stores/index.ts
import { defineStore } from 'pinia'
import Project from '../models/Project';
import { grantAuthSshd, revokeAuth, parseJwt } from '../services/auth';

const initialUser = JSON.parse(sessionStorage.getItem('Orcamento:token') || '{}');

// 导出创建Store的函数,命名更清晰
export const useProjectStore = defineStore('project-store', {
  state: () => ({
    loading: false as boolean,
    // 添加token字段,从sessionStorage初始化
    token: initialUser.token || ''
  }),
  actions: {
    // 修正actions中的赋值错误,对应state里的loading字段
    loadingDataTable(status: boolean) {
      this.loading = status;
    },
  }
});

2. 修正API服务中的Store调用

在请求拦截器内部动态获取Store,确保Pinia实例已激活:

// src/services/api.js
import axios from 'axios';
import { useProjectStore } from '../stores/index';
import { getActivePinia } from 'pinia';

const api = axios.create({ baseURL: import.meta.env.VITE_APP_API_URL });

api.interceptors.request.use(
  (config) => {
    // 确保Pinia实例已创建,再获取Store
    const activePinia = getActivePinia();
    if (activePinia) {
      const store = useProjectStore(activePinia);
      if (store.token) {
        // 修改当前请求的config.headers,而非全局api.config
        config.headers.Authorization = `Bearer ${store.token}`;
      }
    }
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

export default api;

关键说明

  • 避免模块顶级调用Store:Pinia需要在Vue应用实例初始化并安装Pinia插件后才能正常使用Store,因此不能在模块顶级直接调用useProjectStore(),需在运行时回调(如拦截器、组件钩子)中调用。
  • 使用getActivePinia():确保获取到已激活的Pinia实例,防止因实例未初始化导致的错误。
  • 正确修改请求头:拦截器中需修改传入的config对象的headers,该对象对应当前请求的配置,修改后返回才能生效。

内容的提问来源于stack exchange,提问作者Hugo Pedro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 00:41:15