使用通过提供功能全球导入的VUE 3组件中的类

发布于 2025-02-09 03:50:04 字数 3731 浏览 2 评论 0原文

我正在vue 3上构建一个应用程序,其中我为我的API调用构建了一个api类:

import axios from 'axios'

export default class {

    /**
     * Send GET Request
     * @param  {string} url
     * @return {Promise}
     */
    get(url) {
        return new Promise((resolve, reject) => {
            axios.get(url, {}).then(response => {
                if (response.status === 200) {
                    return resolve(response);
                }
            }).catch((error) => {
                return reject(error);
            })
        });
    }

    /**
     * Send POST Request
     * @param  {string} url
     * @param  {object} payload Data object to send
     * @return {Promise}
     */
    post(url, payload) {
        return new Promise((resolve, reject) => {
            axios.post(url, payload, {}).then(response => {
                if (response.status === 200) {
                    return resolve(response);
                }
            }).catch((error) => {
                return reject(error);
            })
        });
    }

    /**
     * Send FIND Request
     * @param  {string} url
     * @return {Promise}
     */
    find(url) {
        return new Promise((resolve, reject) => {
            axios.get(url, {}).then(response => {
                if (response.status === 200) {
                    return resolve(response);
                }
            }).catch((error) => {
                return reject(error);
            })
        });
    }

}

我想在我的vue组件中使用此类功能,为此我导入_API.JS文件和插入.provide('$ api',apis) create> createApp 在app.js中 file:

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 }) {
        return createApp({ render: () => h(app, props) })
            .use(plugin)
            .mixin({ methods: { route } })
            .provide('$api', apis)
            .mount(el);
    },
});

在我的组件中,我使用的是:

<template>
   //HTML Files
</template>
export default {
    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>

使用this。$ api我会遇到错误:

TypeError:无法读取未定义的属性(阅读'post')

屏幕截图:

”错误屏幕截图“

当我尝试console.log(this。$ api)时,它返回undefined

下面的解决方案在VUE 2中工作

vue 2它工作正常:

我只需要在app.js中启动类并添加它到原型,它效果很好。

VUE 2代码app.js

import { App, plugin } from '@inertiajs/inertia-vue'
import Vue from 'vue'
import api from './Models/_api'

const apis = new api();
Vue.prototype.$api = apis;

const el = document.getElementById('app')

new Vue({
    store: store,
    render: h => h(App, {
        props: {
            initialPage: JSON.parse(el.dataset.page),
            resolveComponent: name => import(`NitsPages/${name}`).then(module => module.default),
        },
    }),
}).$mount(el)

I'm building an application on Vue 3 where I've build an api class for my api calls:

import axios from 'axios'

export default class {

    /**
     * Send GET Request
     * @param  {string} url
     * @return {Promise}
     */
    get(url) {
        return new Promise((resolve, reject) => {
            axios.get(url, {}).then(response => {
                if (response.status === 200) {
                    return resolve(response);
                }
            }).catch((error) => {
                return reject(error);
            })
        });
    }

    /**
     * Send POST Request
     * @param  {string} url
     * @param  {object} payload Data object to send
     * @return {Promise}
     */
    post(url, payload) {
        return new Promise((resolve, reject) => {
            axios.post(url, payload, {}).then(response => {
                if (response.status === 200) {
                    return resolve(response);
                }
            }).catch((error) => {
                return reject(error);
            })
        });
    }

    /**
     * Send FIND Request
     * @param  {string} url
     * @return {Promise}
     */
    find(url) {
        return new Promise((resolve, reject) => {
            axios.get(url, {}).then(response => {
                if (response.status === 200) {
                    return resolve(response);
                }
            }).catch((error) => {
                return reject(error);
            })
        });
    }

}

I want to utilize this class functions inside my Vue components, for this I imported the _api.js file and inserted .provide('$api', apis) into createApp function in app.js file:

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 }) {
        return createApp({ render: () => h(app, props) })
            .use(plugin)
            .mixin({ methods: { route } })
            .provide('$api', apis)
            .mount(el);
    },
});

And in my component I'm using as:

<template>
   //HTML Files
</template>
export default {
    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>

while using this.$api I'm getting error:

TypeError: Cannot read properties of undefined (reading 'post')

Screenshot:

error screenshot

when I tried console.log(this.$api) it returned undefined

Below solution working in Vue 2

In Vue 2 it was working perfectly fine:

I only have to initiate the class in app.js and add it to prototype and it works good.

Vue 2 Code app.js:

import { App, plugin } from '@inertiajs/inertia-vue'
import Vue from 'vue'
import api from './Models/_api'

const apis = new api();
Vue.prototype.$api = apis;

const el = document.getElementById('app')

new Vue({
    store: store,
    render: h => h(App, {
        props: {
            initialPage: JSON.parse(el.dataset.page),
            resolveComponent: name => import(`NitsPages/${name}`).then(module => module.default),
        },
    }),
}).$mount(el)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

别挽留 2025-02-16 03:50:05

这与Vue3保留_$前缀有关。

以_或$开头的属性不会在组件实例上代理,因为它们可能与Vue的内部属性和API方法冲突。您将必须这样访问它们。$ data._property。

因此,请尝试以下操作:

this.$data.$api.post(...)

就个人而言,我认为使用这两个常见的惯例并将其保留为内部使用并不理想。但这就是它。您可以在这里阅读更多有关它的信息。
https://github.com/vuejs/vuejs/vue/issues/5879

This is be related to Vue3 reserving _ and $ prefixes.

Properties that start with _ or $ will not be proxied on the component instance because they may conflict with Vue's internal properties and API methods. You will have to access them as this.$data._property.

So try the following:

this.$data.$api.post(...)

Personally, I think using those two common conventions and reserving them for internal use was not ideal. But it is what it is. You can read more about it here.
https://github.com/vuejs/vue/issues/5879

明明#如月 2025-02-16 03:50:05

您可以将API类作为全局属性添加到VUE 3实例。

这在

例如:

main.js

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 app = createApp({ render: () => h(app, props) });
        app.config.globalPoperties.api = apis;
        return 
            .use(plugin)
            .mixin({ methods: { route } })
            .provide('$api', apis)
            .mount(el);
    },
});

然后使用this.api在您的VUE组件中可呼叫

You can add your API Class as a global Property to your Vue 3 Instance.

This is stated in the Vue 3 Application Documentation.

e.g.:

main.js

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 app = createApp({ render: () => h(app, props) });
        app.config.globalPoperties.api = apis;
        return 
            .use(plugin)
            .mixin({ methods: { route } })
            .provide('$api', apis)
            .mount(el);
    },
});

Which will then be callable anywhere inside your Vue Components with this.API

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文