本篇文章同步發表於 2023 iThome 鐵人賽:Nuxt.js 3.x 筆記-打造 SSR 專案
Layouts 資料夾協助我們定義共用模板,將重複使用的版面提取到模板內全域共用,看起來跟 Components 有點像,那麼 Layouts 跟 Components 怎麼區分?可以將 Layouts 視為包覆在頁面外層的包裹元件,用來定義 Header、Sidebar、Footer 等共用版面或是元件
官方文件提到,如果整個專案只有一個模板,建議直接在 app.vue
定義即可
廣告
預設模板
預設模板名稱為 default,新增 layouts/default.vue
,並透過 <slot />
將元件的內容載入
<template> <div> <nav>Header</nav> <slot /> <div>Footer</div> </div> </template>
|
或是將 Header、Footer 等共用元件(Components)加入模板
<template> <div> <TheHeader /> <slot /> <TheFooter /> </div> </template>
|
接著在 app.vue
透過 <NuxtLayout>
元件使用模板,預設使用 layouts/default.vue
模板
<template> <NuxtLayout> <NuxtPage /> </NuxtLayout> </template>
|
新增首頁 pages/index.vue
<template> <div> <h3>Home Page</h3> </div> </template>
|
畫面呈現:
使用其他具名模板
layouts |—— default.vue |—— main.vue
|
<template> <div> <h2>Main Layout</h2> <slot /> </div> </template>
|
1. app.vue 指定全域模板,覆蓋預設模板
使用 name
props 指定模板
名稱必須使用 kebab-case,例如 Layout 檔名為 customLayout,需使用 name='custom-layout'
<template> <NuxtLayout name="main"> <NuxtPage /> </NuxtLayout> </template>
|
2. 在單一元件指定模板
使用 definePageMeta()
輔助函式指定模板名稱
<template> <div>...</div> </template>
<script setup> definePageMeta({ layout: 'main' }); </script>
|
3. 在單一元件直接定義 NuxtLayout
先將預設模板設為 false
,並透過 <NuxtLayout name="xxx">
定義模板
<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()
輔助函式動態切換模板
<template> <div> <h3>Home Page</h3>
<button @click="setPageLayout('default')">default</button> <button @click="setPageLayout('main')">main</button> </div> </template>
|
具名插槽
範例:
layouts/main.vue
搭配具名插槽
<template> <div> <nav>Header</nav> <slot name="content" /> <div>Sidebar</div> <slot name="footer" /> </div> </template>
|
在頁面上使用,需將預設模板設為 false
<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
廣告
評論