Layout components are used to wrap pages. Layouts should contain components like headers, footers or sidebars that will be used across the site.
Layouts are just.vue components located in src/layouts
and need to be declared as a global component or imported per page to be used.
Every layout requires a <slot />
component. This is where the content coming from pages and templates will be inserted. Layouts can have multiple slots.
<!-- Layout -->
<template>
<div>
<header />
<slot /> <!-- Page content will be inserted here -->
<footer />
</div>
</template>
When you have created a layout you need to import it to your pages and templates. This is done inside the <script>
tag.
<!-- Page -->
<template>
<Layout>
Add page content here
</Layout>
</template>
<script>
import Layout from '~/layouts/Default.vue'
export default {
components: {
Layout
}
}
</script>
If you don't want to import the layout into every page or template you can make a layout global. To make a layout global go to src/main.js
and import your layout file into this file.
For example:
// src/main.js
import Layout from '~/layouts/Default.vue'
Then make the layout global inside the export function.
// src/main.js
import Layout from '~/layouts/Default.vue'
export default function (Vue, { head, router, isServer }) {
Vue.component('Layout', Layout)
}
You can now use <Layout>
anywhere in your Gridsome project without importing it to every page:
<!-- Page -->
<template>
<Layout>
Add page content here
</Layout>
</template>
Since layouts work like components, it is possible to pass Props to layouts. For example a page can look like this:
<!-- Page -->
<template>
<Layout :sidebar="true">
Add page content here
</Layout>
</template>
This will pass a Prop to a layout with sidebar = true
. In the Layout component this could look like this:
<!-- Layout -->
<template>
<div>
<div class="main-content">
<slot />
</div>
<div v-if="sidebar">
Lets show the sidebar!
</div>
</div>
</template>
<script>
export default {
props: ['sidebar']
}
</script>
To add multiple slots to a layout you need to name them. In this example we have added a sidebar slot that will only show if the page has sidebar content.
<!-- Layout -->
<template>
<div>
<slot /> <!-- Default slot -->
<div class="sidebar" v-if="$slots.sidebar">
<slot name="sidebar" /> <!-- Sidebar slot -->
</div>
</div>
</template>
Pages can now add content to this slot like this:
<!-- Page -->
<template>
<Layout>
This is the default content
<template slot="sidebar">
This will be added to sidebar slot from the page
</template>
</Layout>
</template>
You can create a master layout by adding a App.vue file to src
root. This will let you keep your header, footer on all pages and add page transitions.
A simple App.vue file looks like this:
<template>
<div id="app">
<router-view />
</div>
</template>