如何在Nuxt的外部JS服务文件中调用store,解决导入后为undefined的问题
问题根因
Nuxt 采用运行时初始化 store 的机制,尤其是开启 SSR/SSG 能力时,静态导入阶段 store 尚未完成实例化,所以直接 import store from '@/store' 必然返回 undefined,不能沿用纯客户端 SPA 的静态导入写法,推荐用 Nuxt 原生的插件机制改造,改动量极小。
改造步骤
步骤1:创建Nuxt插件注入API实例
在项目plugins目录下新建api.js文件:
// plugins/api.js import axios from 'axios' // 统一导入你所有的10个业务服务,按实际路径调整即可 import userService from '@/services/user' import orderService from '@/services/order' // ... 剩余8个业务服务依次导入 export default defineNuxtPlugin((nuxtApp) => { // Nuxt2写法替换为:export default ({ store, $pinia }, inject) => { // 从运行时上下文取store,保证实例已完成初始化,兼容Vuex/Pinia const store = nuxtApp.$store || useStore() // 创建axios基础实例 const axiosInstance = axios.create({ baseURL: `http://myip.com/` }) // 新增请求拦截器动态获取最新token,避免token更新后实例缓存旧值 axiosInstance.interceptors.request.use(config => { if (store.state.token) { config.headers.Authorization = `Bearer ${store.state.token}` } return config }) // 给所有业务服务绑定axios实例 const apiServices = { user: userService(axiosInstance), order: orderService(axiosInstance), // ... 剩余8个服务依次注册 } // 注入到Nuxt全局实例,无需手动导入即可在全项目调用 return { provide: { api: apiServices } } })
步骤2:批量改造原有业务服务文件
不需要再导入Api实例,改成接收axios实例作为入参即可,10个业务文件统一按这个格式调整:
// services/user.js 即你原来的登录注册业务文件 export default (axios) => { return { register (credentials){ return axios.post('register', credentials) }, login (credentials){ return axios.post('login', credentials) } } }
步骤3:注册插件到Nuxt配置
- Nuxt3:插件放在
plugins目录下默认自动注册,无需额外配置 - Nuxt2:在
nuxt.config.js中新增配置项:
export default { plugins: [ '~/plugins/api.js' ] }
步骤4:在.vue文件中调用
无需手动导入业务服务,直接调用全局注入的$api即可:
<!-- 选项式API写法 --> <script> export default { methods: { async handleLogin(formData) { const res = await this.$api.user.login(formData) // 后续业务逻辑 } } } </script> <!-- 组合式API写法 --> <script setup> const { $api } = useNuxtApp() const handleLogin = async (formData) => { const res = await $api.user.login(formData) } </script>
内容的提问来源于stack exchange,提问作者Jumper
相关产品推荐
相关产品推荐

