Inertia Guidelines¶
Page & Layout Components (Partials)¶
Partials are smaller parts of a page or layout, intended solely to reduce the amount of code within a single component and simplify the codebase. These are single-use components.
Naming Convention¶
To keep partials scoped and separate, follow this naming convention:
{ParentComponentName}{PartialName}.vue
For instance, if ListingShowPage.vue
includes a partial for the vehicle details, the file name would be:
ListingShowPageVehicleDetailPanel.vue
Placement¶
- Make a
partials
directory in the same directory as the parent page component - Make a directory inside the
partials
directory for each partial
/inertia/views/pages/listings/show
├── ListingShowPage.vue
└── /partials
└── /vehicle-details-panel
├── ListingShowPageVehicleDetailPanel.stories.js
├── ListingShowPageVehicleDetailPanel.vue
└── ListingShowPageVehicleDetailPanelItem.vue
Storybook¶
Put Storybook stories for partials in the same directory as the partial.
In order to scope partial stories, use the following naming convention:
title: 'Pages/{PageName}/{ComponentName}',
title: 'Pages/ListingShow/Vehicle Details Panel',
Page Props¶
When passing data from the inertia()
PHP function to Inertia page components, use the props
property in the component to define the expected props.
Prefer
<template>
<div>
<h1>{{ listing.title }}</h1>
<p>{{ listing.description }}</p>
</div>
</template>
<script>
export default {
props: {
listing: {
type: Object,
required: true,
},
},
};
</script>
Avoid
<template>
<div>
<h1>{{ $page.props.listing.title }}</h1>
<p>{{ $page.props.listing.description }}</p>
</div>
</template>
Note
It is fine to use $page.props
to access globally shared props, such as the user object.
These are passed by the HandleInertiaRequests
middleware.
Communication Between Components¶
Direct Communication¶
For direct communication between parent and child components, use standard Vue events.
<button @click="$emit('someEvent')">
Click me
</button>
<my-component @some-event="callback" />
However, if you find the need to bubble the event up to the parent's parent, or even higher, consider using the Store.
Indirect Communication¶
The goal is to limit the number of techniques used for communication between components.
Prefer using the Pinia Store
Avoid using this.$root
Avoid using EventHub
We have Pinia Store available. Prefer it over other techniques when dealing with indirect communication between components. Example:
export const useModalStore = defineStore('modal', () => {
const isModalSortOpen = ref(false);
function openModalSort() {
isModalSortOpen.value = true;
}
return {
isModalSortOpen,
openModalSort,
};
});
<template>
<button @click="modalStore.openModalSort">
Open modal
</button>
</template>
<script>
import { useModalStore } from './modal-store.js';
export default {
setup() {
const modalStore = useModalStore();
return {
modalStore,
};
},
};
</script>