Let's start talking about layouts. Our current main problem is duplication of the menu code for Posts and About pages.
First, we need a Vue component as the main layout. We will create a new folder resources/js/Layouts
and a Vue component, App.vue
inside it.
Move the repeating code from the Posts/Index.vue
and About.vue
Vue components to the Layouts/App.vue
Vue component.
resources/js/Pages/Posts/Index.vue:
<script setup>import { Link } from '@inertiajs/vue3'; const props = defineProps({ posts: { type: Object, required: true }})</script> <template> <div class="mb-4"> <Link class="mr-2" :href="route('posts.index')">Posts</Link> <Link :href="route('about')">About</Link> </div> // ...</template>
resources/js/Pages/About.vue:
<script setup> import { Link } from '@inertiajs/vue3';</script> <template> <div class="mb-4"> <Link class="mr-2" :href="route('posts.index')">Posts</Link> <Link :href="route('about')">About</Link> </div> <div>About us</div></template>
resources/js/Layouts/App.vue:
<script setup>import { Link } from '@inertiajs/inertia-vue3'</script> <template> <div class="mb-4"> <Link class="mr-2" :href="route('posts.index')">Posts</Link> <Link :href="route('about')">About</Link> </div></template>
To tell Vue where to add the content, use slots, the same as with Blade.
resources/js/Layouts/App.vue:
<script setup>import { Link } from '@inertiajs/inertia-vue3'</script> <template> <div class="mb-4"> <Link class="mr-2" :href="route('posts.index')">Posts</Link> <Link :href="route('about')">About</Link> </div> <slot /> </template>
How do you use that App
layout? We must import it into the Vue component and surround everything with it.
Also, we can use different name when importing and then surround with that name. I choose the AppLayout
name.
resources/js/Pages/Posts/Index.vue:
<script setup>import AppLayout from '../../Layouts/App.vue'; const props = defineProps({ posts: { type: Object, required: true }})</script> <template> <AppLayout> <table class="min-w-full divide-y divide-gray-200 border"> // ... </AppLayout> </template>
resources/js/Pages/About.vue:
<script setup> import AppLayout from '../Layouts/App.vue';</script> <template> <AppLayout> <div>About us</div> </AppLayout> </template>
Visually, nothing changes, but now we don't have duplicate code.
In this lesson, "along the way", let's also add a CSS class to indicate which links in the menu are active.
There are a few ways to do that. In this lesson, we will use the route()
function to check if the route is active.
resources/js/Layouts/App.vue:
// ... <template> <div class="mb-4"> <Link class="mr-2" :href="route('posts.index')">Posts</Link> <Link :href="route('about')">About</Link> <Link class="mr-2" :href="route('posts.index')" :class="{ 'font-bold underline': route().current('posts.index') }">Posts</Link> <Link :href="route('about')" :class="{ 'underline': route().current('about') }">About</Link> </div> <slot /></template>
Now, we have one main layout with the links, and from that layout, we build all the pages in the future lessons.