简体   繁体   English

使用 Vue 3 在 InertiaJS 中定义全局组件

[英]Define global component in InertiaJS with Vue 3

I'm trying to build an application on Laravel 8.38 - InertiaJS 0.8.4 I'm using Vue 3 as my frontend stack.我正在尝试在Laravel 8.38 - InertiaJS 0.8.4上构建应用程序我使用Vue 3作为我的前端堆栈。

I've multiple layouts which I need to register globally as Vue Component, so that I can use it in my application anywhere.我有多个布局,需要在全局范围内注册为Vue组件,以便我可以在任何地方的应用程序中使用它。 I'm unable to do so, my code:我无法这样做,我的代码:

import { createApp, h } from 'vue';
import { App as InertiaApp, plugin as InertiaPlugin } from '@inertiajs/inertia-vue3';

const el = document.getElementById('app');

const app = createApp({
    render: () =>
        h(InertiaApp, {
            initialPage: JSON.parse(el.dataset.page),
            resolveComponent: (name) => require(`./../Pages/${name}`).default,
        }),
})
    .mixin({ methods: { route } })
    .use(InertiaPlugin);

app.component('app-market', () => import('./../layouts/AppMarketLayout')); //trying to import layout

app.mount(el);

And inside the page I'm trying to call this layout component:在页面内部,我试图调用这个布局组件:

<template>
    <div>
        <app-market-layout></app-market-layout>
    </div>
</template>

Unable to fetch, no errors in console.无法获取,控制台中没有错误。

I was having 2 layouts for backend(admin-panel) and frontend(website), achieved as follows.我有后端(管理面板)和前端(网站)的 2 个布局,实现如下。 Using inertia default middleware file.使用惯性默认中间件文件。

project/app/Http/Middleware/HandleInertiaRequests.php项目/app/Http/Middleware/HandleInertiaRequests.php

class HandleInertiaRequests extends Middleware
{
    protected $rootView = 'app';

    public function rootView(Request $request)
    {
        if ($request->segments()[0] == 'admin') {
            return 'admin';
        }

        return parent::rootView($request);
    }

    public function version(Request $request)
    {
        return parent::version($request);
    }

    public function share(Request $request)
    {
        return array_merge(parent::share($request), [
            //
        ]);
    }
}

project/resources/js/Shared/Frontend/Layouts/Layout.vue项目/资源/js/Shared/Frontend/Layouts/Layout.vue

<template>

    <Header />

    <slot />

    <Footer />

</template>

<script>
    import Header from '../Partials/Header'
    import Footer from '../Partials/Footer'
    export default {
        components: {
            Header,
            Footer
        },

        name: "FrontendLayout"
    }
</script>

project/resources/js/Pages/Frontend/Auth/Login.vue项目/资源/js/Pages/Frontend/Auth/Login.vue

<template>
    ...
</template>

<script>
    import Layout from '@/js/Shared/Frontend/Layouts/Layout';
    export default {
        
        layout: Layout,

        metaInfo: { title: 'Login' },

        data() {
            return {
                form: this.$inertia.form({
                    'email': '',
                    'password': '',
                    'remember': false
                })
            }
        },

        methods: {
            submit() {
                this.form.post(route('login.store'))
            }
        }
    }
</script>

In Inertia JS, importing components globally is a little different than using a normal Vue configuration.在 Inertia JS 中,全局导入组件与使用普通 Vue 配置有点不同。

In your app.js file, you need to import the component(either inline or at the top of the file), then add the component before mounting the vue instance.在您的 app.js 文件中,您需要导入组件(内联或文件顶部),然后在挂载 vue 实例之前添加组件。

So, in your case, the configuration should look like the below:因此,在您的情况下,配置应如下所示:

import { createApp, h } from 'vue';
import { App as InertiaApp, plugin as InertiaPlugin } from '@inertiajs/inertia-vue3';

//Import the component:
import AppMarket from "./../layouts/AppMarketLayout"; 

const el = document.getElementById('app');

const app = createApp({
    render: () =>
        h(InertiaApp, {
            initialPage: JSON.parse(el.dataset.page),
            resolveComponent: (name) => require(`./../Pages/${name}`).default,
        }),
})
    .mixin({ methods: { route } })
    .mixin({ components: { AppMarket } }) // << Then tell the inertia 
             // instance to use the component. 
             // You can also add this to the other mixin declaration
    .use(InertiaPlugin)
    .mount(el);

Then, in your template, you can use the component like this:然后,在您的模板中,您可以像这样使用组件:

<template>
    <app-market>
    </app-market>
</template>

I noticed in your original post you are trying to use the component as app-market-layout.我在您的原始帖子中注意到您正在尝试将该组件用作应用市场布局。 You must import the component with that name if you plan to do that.如果您打算这样做,则必须导入具有该名称的组件。

The configuration would look like this in app.js: app.js 中的配置如下所示:

import { createApp, h } from 'vue';
import { App as InertiaApp, plugin as InertiaPlugin } from '@inertiajs/inertia-vue3';

//Import the component: Notice the component name change.
import AppMarketLayout from "./../layouts/AppMarketLayout"; 

const el = document.getElementById('app');

const app = createApp({
    render: () =>
        h(InertiaApp, {
            initialPage: JSON.parse(el.dataset.page),
            resolveComponent: (name) => require(`./../Pages/${name}`).default,
        }),
})
    .mixin({ methods: { route } })
    .mixin({ components: { AppMarketLayout } }) // << Here the component name has Layout
    .use(InertiaPlugin)
   
    .mount(el);

Then in your template:然后在您的模板中:

<template>
    <app-market-layout>
    </app-market-layout>
</template>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM