v-slot‘s in Vue.js is same as passing a child element in React.js. The slots will have all its own properties along with the properties elements being passed to it. v-slot‘s are popular for structuring layouts, defining element boundaries, etc. Here in this example, I’m going to show how you can create a basic website layout containing header, main and the footer elements using the v-slot.
Here’s my Layout.vue which uses slot with predefined slot names:
<template>
<div>
<header class="header-slot">
<slot name="header"></slot>
</header>
<main class="main-slot">
<slot></slot>
</main>
<footer class="footer-slot">
<slot name="footer"></slot>
<div class="np-credits">wwww.nightprogrammer.com</div>
</footer>
</div>
</template>
<script>
export default {
name: "Layout",
};
</script>
<style scoped>
.header-slot {
background: #eee;
padding: 10px 6px;
}
.main-slot {
padding: 16px 6px;
}
.footer-slot {
background: #eee;
padding: 10px 6px;
}
</style>
Code language: HTML, XML (xml)
In the above code, I’ve created three slots one with a name of header, one with a name of footer, and one without any name (for main). I’ve also added some CSS styles to each of the slot containers. You’d notice that I’ve placed a footer link below the footer slot. It means that, whenever a component uses this layout, the footer will always show the link.
Here’s my App.vue file which uses the above component as a Layout:
<template>
<div id="app">
<layout>
<template v-slot:header>
<h1>Header</h1>
</template>
<template v-slot:default>
<h2>Some content</h2>
<p>Some paragraph</p>
</template>
<template v-slot:footer>
<p>Footer</p>
</template>
</layout>
</div>
</template>
<script>
import Layout from "./Layout";
export default {
name: "App",
components: {
Layout,
},
};
</script>
<style>
#app {
font-family: "Avenir", Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
* {
margin: 0;
padding: 0;
}
.np-credits {
font-size: 12px;
margin-top: 12px;
color: #4b4b4b;
}
</style>
Code language: HTML, XML (xml)
In the above file, I’ve imported the Layout.vue component and then passed in some content to each of the slots.
The above code when executed will produce the following output:
You can find a working demo of the above code from my repo links below: