Reputation: 157
I'm trying to build an application on Laravel 8.38 - InertiaJS 0.8.4
I'm using Vue 3
as my frontend stack.
I've multiple layouts which I need to register globally as Vue
Component, so that I can use it in my application anywhere. 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.
Upvotes: 8
Views: 8221
Reputation: 144
In latest Inertia, Just import the 'Link' component and added .component("Link", Link) between .use() and .mount()
import { createApp, h } from 'vue';
import {createInertiaApp, Link} from '@inertiajs/inertia-vue3';
import { InertiaProgress } from '@inertiajs/progress'
createInertiaApp({
resolve: name => {
const pages = import.meta.glob('./Pages/**/*.vue', { eager: true })
return pages[`./Pages/${name}.vue`]
},
setup({ el, App, props, plugin }) {
createApp({ render: () => h(App, props) })
.use(plugin)
.component("Link", Link)
.mount(el)
},
});
Upvotes: 1
Reputation: 7
In Inertia JS, importing components globally is the same as using a normal Vue configuration.
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. You can either do this as a mixin, or as a component.
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:
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>
Upvotes: 2
Reputation: 7338
I was having 2 layouts for backend(admin-panel) and frontend(website), achieved as follows. Using inertia default middleware file.
project/app/Http/Middleware/HandleInertiaRequests.php
class HandleInertiaRequests extends Middleware
{
protected $rootView = 'app';
public function rootView(Request $request)
{
if ($request->segment(1) == '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
<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
<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>
Upvotes: 1