Nuxt.js 3.x Layouts 目錄-自訂模板

本篇文章同步發表於 2023 iThome 鐵人賽:Nuxt.js 3.x 筆記-打造 SSR 專案

Layouts 資料夾協助我們定義共用模板,將重複使用的版面提取到模板內全域共用,看起來跟 Components 有點像,那麼 Layouts 跟 Components 怎麼區分?可以將 Layouts 視為包覆在頁面外層的包裹元件,用來定義 Header、Sidebar、Footer 等共用版面或是元件

官方文件提到,如果整個專案只有一個模板,建議直接在 app.vue 定義即可

廣告

預設模板

預設模板名稱為 default,新增 layouts/default.vue,並透過 <slot /> 將元件的內容載入

// layouts/default.vue
<template>
<div>
<nav>Header</nav>
<slot />
<div>Footer</div>
</div>
</template>

或是將 Header、Footer 等共用元件(Components)加入模板

// layouts/default.vue
<template>
<div>
<TheHeader />
<slot />
<TheFooter />
</div>
</template>

接著在 app.vue 透過 <NuxtLayout> 元件使用模板,預設使用 layouts/default.vue 模板

// app.vue
<template>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</template>

新增首頁 pages/index.vue

// pages/index.vue
<template>
<div>
<h3>Home Page</h3>
</div>
</template>

畫面呈現:


使用其他具名模板

layouts
|—— default.vue
|—— main.vue
// layouts/main.vue
<template>
<div>
<h2>Main Layout</h2>
<slot />
</div>
</template>

1. app.vue 指定全域模板,覆蓋預設模板

使用 name props 指定模板

名稱必須使用 kebab-case,例如 Layout 檔名為 customLayout,需使用 name='custom-layout'

// app.vue
<template>
<NuxtLayout name="main">
<NuxtPage />
</NuxtLayout>
</template>

2. 在單一元件指定模板

使用 definePageMeta() 輔助函式指定模板名稱

// pages/index.vue
<template>
<div>...</div>
</template>

<script setup>
definePageMeta({
layout: 'main'
});
</script>

3. 在單一元件直接定義 NuxtLayout

先將預設模板設為 false,並透過 <NuxtLayout name="xxx"> 定義模板

// pages/index.vue
<template>
<div>
<NuxtLayout name="main">
<h3>Home Page</h3>
</NuxtLayout>
</div>
</template>

<script setup>
definePageMeta({
layout: false
});
</script>

在單一元件直接使用 <NuxtLayout>,要避免放在 根元素(root element),或是關閉 page 跟 layout 的 transitions 效果

畫面呈現:


動態切換模板

透過 setPageLayout() 輔助函式動態切換模板

// pages/index.vue
<template>
<div>
<h3>Home Page</h3>

<button @click="setPageLayout('default')">default</button>
<button @click="setPageLayout('main')">main</button>
</div>
</template>

具名插槽

範例:
layouts/main.vue 搭配具名插槽

// layouts/main.vue
<template>
<div>
<nav>Header</nav>
<slot name="content" />
<div>Sidebar</div>
<slot name="footer" />
</div>
</template>

在頁面上使用,需將預設模板設為 false

// pages/index.vue
<template>
<div>
<NuxtLayout name="main">
<template #content>
<h3>Home Page</h3>
</template>

<template #footer>
<h3>Footer</h3>
</template>
</NuxtLayout>
</div>
</template>

<script setup>
definePageMeta({
layout: false
});
</script>

參考資源:

https://nuxt.com/docs/guide/directory-structure/layouts
https://nuxt.com/docs/examples/features/layouts
https://medium.com/codex/nuxt3-layouts-276ed64a4a1c

廣告
Nuxt.js 3.x 導入 I18n 實作多國語系 Nuxt.js 3.x Server 目錄-建立 API

評論

廣告
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×