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

Vue3 provide全局注入API类 组件this.$api为undefined报错

问题原因

你遇到的this.$api为undefined的问题核心是两个API使用误区:

  1. Vue3的provide/inject机制不会自动将注入值绑定到组件实例this上,必须在每个使用的组件内显式通过inject声明接收,才能访问注入内容,直接读this.$api自然是undefined。
  2. Vue3已经移除了Vue2中通过Vue.prototype挂载全局属性的写法,直接照搬旧版本逻辑无法生效。
解决方案

两种实现方式选其一即可,第一种更贴合你Vue2的使用习惯,不需要修改现有组件的调用代码。

方案1:全局属性挂载(推荐)

这是Vue3官方提供的替代Vue.prototype的方案,挂载后所有组件可以直接通过this.$api访问实例,完全兼容你现有组件的调用写法。
只需要修改app.js的配置,把原来的.provide('$api', apis)替换为全局属性挂载即可,修改后代码如下:

import { createApp, h } from 'vue';
import { createInertiaApp } from '@inertiajs/inertia-vue3';
import api from './Models/_api'

const apis = new api();

createInertiaApp({
    resolve: (name) => require(`./Pages/${name}.vue`),
    setup({ el, app, props, plugin }) {
        const appInstance = createApp({ render: () => h(app, props) })
            .use(plugin)
            .mixin({ methods: { route } })
        // 全局挂载api实例,替代原provide写法
        appInstance.config.globalProperties.$api = apis;
        return appInstance.mount(el);
    },
});

改完后组件里原有的this.$api.post()等调用逻辑不需要任何修改,可直接正常运行。

方案2:正确使用provide/inject注入

如果你坚持用provide做依赖注入,需要在每一个调用$api的组件里显式声明inject接收注入值,才能正常访问。
app.js里的provide写法不需要改动,只需要修改组件代码,添加inject声明:

<template>
   // 页面HTML内容
</template>
<script>
export default {
    // 必须显式声明接收注入的$api
    inject: ['$api'],
    data(){
        return{
            tableData:[],
        }
    },
    methods:{
        fetchData(){
            this.$api.post('/api/user-data', {}).then(response=>{
                if(response.status === 200)
                {
                    this.tableData = response.data.data
                }
            });
        }
    },
    created(){
        this.fetchData();
    },
}
</script>

如果后续用<script setup>的组合式API写法,需要在setup内通过const $api = inject('$api')的方式接收,不能通过this访问。

额外代码优化建议

你目前写的api类存在冗余包装,axios本身就返回Promise,不需要额外套一层new Promise,还可以提前创建axios实例统一做全局配置,简化后的代码参考:

import axios from 'axios'

// 统一创建axios实例,可配置baseURL、全局请求/响应拦截器、超时时间等
const request = axios.create({
    timeout: 10000
})

export default class {
    get(url, params = {}) {
        return request.get(url, { params }).then(res => res.data)
    }
    post(url, payload = {}) {
        return request.post(url, payload).then(res => res.data)
    }
    find(url) {
        // find和get逻辑完全一致,直接复用get方法即可
        return this.get(url)
    }
}

axios默认会把所有非2xx状态的请求自动抛到catch分支,不需要你每次手动判断response.status === 200,能减少很多重复代码。

内容的提问来源于stack exchange,提问作者Rubal Gulati

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 14:31:14