С Inertia каждая страница Вашего приложения имеет собственный контроллер и соответствующий компонент JavaScript. Это позволяет получать только те данные, которые необходимы для этой страницы, без использования API.
Страницы - это просто компоненты JavaScript. В них нет ничего особенного. Страницы получают данные от контроллеров как реквизиты. Вот пример простого компонента страницы.
<template>
<layout title="Добро пожаловать">
<h1>Добро пожаловать</h1>
<p>Здравствуйте, {{ user.name }}, добро пожаловать в Ваше первое приложение Inertia!</p>
</layout>
</template>
<script>
import Layout from './Layout'
export default {
components: {
Layout,
},
props: {
user: Object,
},
}
</script>
Хотя это и не обязательно, для большинства проектов имеет смысл создать макет сайта, который можно расширять. Обратите внимание, что в нашем примере страницы выше мы помещаем содержимое страницы в компонент <layout>
. Вот пример такого компонента. Здесь нет ничего специфичного для Inertia. Это просто стандартный компонент JavaScript.
<template>
<main>
<header>
<inertia-link href="/">Главная</inertia-link>
<inertia-link href="/about">О нас</inertia-link>
<inertia-link href="/contact">Контакты</inertia-link>
</header>
<article>
<slot />
</article>
</main>
</template>
<script>
export default {
props: {
title: String,
},
watch: {
title: {
immediate: true,
handler(title) {
document.title = title
},
},
},
}
</script>
Хотя реализовать макеты как дочерние элементы компонентов страницы просто, это заставляет экземпляр макета уничтожаться и воссоздавать его между посещениями. Это означает, что у Вас не может быть постоянного состояния макета при переходе между страницами.
Например, возможно, у Вас есть аудиоплеер на веб-сайте подкастов, который Вы хотите продолжать воспроизводить, когда пользователи будут перемещаться по сайту. Или, может быть, Вы просто хотите сохранить позицию прокрутки в навигации между посещениями страницы. В таких ситуациях лучше использовать функцию постоянных макетов в Inertia.
<template>
<div>
<h1>Добро пожаловать</h1>
<p>Здравствуйте, {{ user.name }}, добро пожаловать в Ваше первое приложение Inertia!</p>
</div>
</template>
<script>
import Layout from './Layout'
export default {
// Использование функции рендеринга
layout: (h, page) => h(Layout, [page]),
// Сокращение
layout: Layout,
props: {
user: Object,
},
}
</script>
Вы также можете создавать более сложные компоновки макетов, используя вложенные макеты.
<template>
<div>
<h1>Добро пожаловать</h1>
<p>Здравствуйте, {{ user.name }}, добро пожаловать в ваше первое приложение Inertia!</p>
</div>
</template>
<script>
import SiteLayout from './SiteLayout'
import NestedLayout from './NestedLayout'
export default {
// Использование функции рендеринга
layout: (h, page) => {
return h(Layout, () => h(GreenLayout, () => page))
},
// Использование сокращения
layout: [SiteLayout, NestedLayout],
props: {
user: Object,
},
}
</script>
Если Вы используете постоянные макеты, можно установить макет страницы по умолчанию в обратном вызове resolveComponent()
.
import Layout from './Layout'
resolveComponent: name => import(`./Pages/${name}`)
.then(({ default: page }) => {
if (page.layout === undefined) {
page.layout = Layout
}
return page
}),
Это автоматически установит макет страницы на Layout
, если макет еще не был установлен для этой страницы. При необходимости Вы можете отключить макет по умолчанию на определенных страницах, установив для параметра layout
значение null
.
Вы даже можете пойти дальше и условно установить макет страницы по умолчанию на основе имени страницы name
, доступного для метода resolveComponent()
. Например, Вы не хотите, чтобы макет по умолчанию применялся к Вашим общедоступным страницам.
import Layout from './Layout'
resolveComponent: name => import(`./Pages/${name}`)
.then(({ default: page }) => {
if (page.layout === undefined && !name.startsWith('Public/')) {
page.layout = Layout
}
return page
}),
Хотя можно передавать реквизиты заголовков и метатегов со страниц в макеты (как показано выше), часто проще управлять этим с помощью библиотеки заголовка документа, такой как Vue Meta или React Helmet. Svelte имеет встроенную поддержку для управления заголовком документа с помощью элемента <svelte:head>
.
<template>
<layout>
<h1>Добро пожаловать</h1>
<p>Здравствуйте, {{ user.name }}, добро пожаловать в Ваше первое приложение Inertia!</p>
</layout>
</template>
<script>
import Layout from './Layout'
export default {
metaInfo() {
return {
title: `Добро пожаловать ${this.user.name}`,
}
},
components: {
Layout,
},
props: {
user: Object,
},
}
</script>
Если Вы используете Vue 3, Вы также можете использовать для этого функцию телепорт:
<template>
<teleport to="head">
<title>Добро пожаловать {{ user.name }}</title>
</teleport>
</template>
Кроме того, если для Вашего приложения критически важно установить заголовок страницы и метатеги на стороне сервера, Вы можете использовать данные корневого шаблона для этого.