使用 Inertia 构建应用程序时,您的应用程序中的每个页面通常都有自己的控制器/路由和相应的 JavaScript 组件。这使您可以仅检索该页面所需的数据 - 无需 API。
此外,页面所需的所有数据都可以在浏览器渲染页面之前检索,从而无需在用户访问您的应用程序时显示“加载”状态。
Inertia 页面只是 JavaScript 组件。如果您曾经编写过 Vue、React 或 Svelte 组件,您会感觉宾至如归。正如您在下面的示例中看到的,页面从您的应用程序的控制器接收数据作为 props。
<script setup>
import Layout from './Layout'
import { Head } from '@inertiajs/vue3'
defineProps({ user: Object })
</script>
<template>
<Layout>
<Head title="Welcome" />
<h1>Welcome</h1>
<p>Hello {{ user.name }}, welcome to your first Inertia app!</p>
</Layout>
</template>
鉴于上面的页面,您可以通过从控制器或路由返回一个 Inertia 响应 来渲染页面。在这个例子中,让我们假设这个页面存储在 Laravel 应用程序中的 resources/js/Pages/User/Show.vue
中。
use Inertia\Inertia;
class UserController extends Controller
{
public function show(User $user)
{
return Inertia::render('User/Show', [
'user' => $user
]);
}
}
虽然不是必需的,但对于大多数项目来说,创建所有页面都可以扩展的站点布局是有意义的。您可能已经注意到,在我们上面的页面示例中,我们将页面内容包装在 <Layout>
组件中。以下是一个此类组件的示例
<script setup>
import { Link } from '@inertiajs/vue3'
</script>
<template>
<main>
<header>
<Link href="/">Home</Link>
<Link href="/about">About</Link>
<Link href="/contact">Contact</Link>
</header>
<article>
<slot />
</article>
</main>
</template>
如您所见,此模板中没有 Inertia 特定的内容。这只是一个典型的 Vue 组件。
虽然将布局作为页面组件的子级来实现很简单,但这会强制布局实例在访问之间被销毁和重新创建。这意味着您在页面之间导航时无法拥有持久布局状态。
例如,也许您在播客网站上有一个音频播放器,您希望它在用户浏览网站时继续播放。或者,也许您只是想在页面访问之间维护侧边栏导航中的滚动位置。在这些情况下,解决方案是利用 Inertia 的持久布局。
<script>
import Layout from './Layout'
export default {
// Using a render function...
layout: (h, page) => h(Layout, [page]),
// Using shorthand syntax...
layout: Layout,
}
</script>
<script setup>
defineProps({ user: Object })
</script>
<template>
<H1>Welcome</H1>
<p>Hello {{ user.name }}, welcome to your first Inertia app!</p>
</template>
您还可以使用嵌套布局创建更复杂的布局安排。
<script>
import SiteLayout from './SiteLayout'
import NestedLayout from './NestedLayout'
export default {
// Using a render function...
layout: (h, page) => {
return h(SiteLayout, () => h(NestedLayout, () => page))
},
// Using the shorthand...
layout: [SiteLayout, NestedLayout],
}
</script>
<script setup>
defineProps({ user: Object })
</script>
<template>
<H1>Welcome</H1>
<p>Hello {{ user.name }}, welcome to your first Inertia app!</p>
</template>
如果您使用的是 Vue 2.7 或 Vue 3,您可以选择使用 defineOptions 插件 在 <script setup>
中定义布局
<script setup>
import Layout from './Layout'
defineOptions({ layout: Layout })
</script>
如果您使用的是持久布局,您可能会发现,在应用程序主 JavaScript 文件的 resolve()
回调中定义默认页面布局很方便。
import Layout from './Layout'
createInertiaApp({
resolve: name => {
const pages = import.meta.glob('./Pages/**/*.vue', { eager: true })
let page = pages[`./Pages/${name}.vue`]
page.default.layout = page.default.layout || Layout
return page
},
// ...
})
如果尚未为该页面设置布局,这将自动将页面布局设置为 Layout
。
您甚至可以更进一步,根据页面 name
有条件地设置默认页面布局,该名称可用于 resolve()
回调。例如,也许您不希望默认布局应用于您的公共页面。
import Layout from './Layout'
createInertiaApp({
resolve: name => {
const pages = import.meta.glob('./Pages/**/*.vue', { eager: true })
let page = pages[`./Pages/${name}.vue`]
page.default.layout = name.startsWith('Public/') ? undefined : Layout
return page
},
// ...
})