开发者问题收集

无法使用 Pinia 调用 API 内的商店

2022-09-20
1884

我正在使用 Vue 3.2 <script setup> ,如果我尝试在 API 服务中访问 Pinia 的存储,则会引发以下错误;

未捕获的 ReferenceError:在 api.js?:9:1 (anonymous) @ api.js?9:9 初始化之前无法访问“存储”

src/services/api.js:

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

// eslint-disable-next-line no-undef

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;
    },
  }
});

我尝试使用 Pinia 的拦截器,但错误仍然存​​在:

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

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

// use interceptors
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个回答

问题在于 services/api.jsstores/index.ts 模块之间存在间接循环依赖,以至于无法正确评估它们。

useProject() 返回一个单例,用函数包装商店的原因之一是,这可以防止它被过早访问。 Pinia 商店应该仅在初始化 Pinia 后才可访问,否则将需要按照特定顺序评估依赖于它的模块,而这并不容易实现。

在这种情况下, useProject 应该就地使用,而不是在模块评估时使用:

api.interceptors.request.use(
  (config) => {
    const store = useProject();
    const { token } = store;
    ...

由于 ES 模块的工作方式,这允许解决循环依赖。

避免循环依赖的一种方法是将此代码从 services/api.js 移动到 stores/index.ts 不依赖的另一个模块,例如入口点。

Estus Flask
2022-09-20