頁面

當使用 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 回應 來渲染頁面。在此範例中,我們假設此頁面儲存在 resources/js/Pages/User/Show.vue Laravel 應用程式中。

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
  },
  // ...
})