Let’s create a multi-layout Vue 3 application using Vue Router. We will make a group of routes and give each group a layout. so that we can make a layout for the home page, a layout for the profile page, a layout for the blog, etc.
I have a fresh Vite Vue 3 project with bootstrap 5 and bootstrap Icon installed. if you are not okay with that Here is the tutorial: How To Install Bootstrap 5 In Vue 3 With Bootstrap Icons
If you are okay skip it and let’s continue.
Here is the YouTube video for this is tutorial
Install Vue Router
Let’s install Vue-router, I’m using NPM,
npm install vue-router@4
yarn add vue-router@4
We need to create a new file src\router\index.js
for adding our routes
import { createRouter, createWebHistory } from 'vue-router'
import Home from '/src/views/Home.vue'
import About from '/src/views/About.vue'
const routes = [
{
path:'/',
name:'Home',
component:Home
},
{
path:'/',
name:'About',
component:About
}
]
const router = createRouter({
history: createWebHistory(),
routes,
})
export default router
We are using History mode for Vue Router and created two routers for the Home page and About page. Let’s add the router to our Vue app in src\main.js
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import "bootstrap/dist/css/bootstrap.min.css"
import "bootstrap"
import "bootstrap-icons/font/bootstrap-icons.css"
import router from "./router"
createApp(App).use(router).mount('#app')
View Components
We will put our pages in the “view” folder in “src” so let’s create our pages. src\views\Home.vu
e & src\views\About.vue
<template>
<div>this is about</div>
</template>
<template>
<div>this is home</div>
</template>
Finally, app.vue
let’s add the navigation links.
<template>
<nav>
<ul>
<li><router-link :to="{name:'Home'}"> Home </router-link></li>
<li><router-link :to="{name:'About'}"> About </router-link></li>
</ul>
</nav>
<router-view/>
</template>
Now run the dev server and test the route links.
npm run dev
Vue Layout
Let’s create our first layout for the home page. We will create a folder named “layouts” for all layouts. Let’s create our layout file src\layouts\DefaultLayout.vue
<template>
<div>
<AppHeader/>
<router-view/>
<AppFooter/>
</div>
</template>
<script>
import AppHeader from '../components/AppHeader.vue'
import AppFooter from '../components/AppFooter.vue'
export default {
components:{AppHeader,AppFooter}
}
</script>
We added <router-view/>
component, exactly as we did in the app.vue
in addition to creating the app header and footer components.
Make sure the app.vue
has only the <router-view/>
component and remove the other HTML elements
<template>
<router-view v-if="this.$store.state.stateLoaded"></router-view>
</template>
We can add some code to our AppHeader
and AppFooter
now.
<template>
<nav class="navbar navbar-expand-lg bg-light">
<div class="container-fluid">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<router-link :to="{name:'Home'}" class="nav-link active" aria-current="page" href="#">Home</router-link>
</li>
<li class="nav-item">
<router-link :to="{name:'About'}" class="nav-link" aria-current="page" href="#">About</router-link>
</li>
</ul>
</div>
</div>
</nav>
</template>
<template>
<div>Footer</div>
</template>
Now let’s create another layout for the “about” page but without a header or a footer, src\layouts\AboutLayout.vue
<template>
<div>
About page header
<router-view/>
About page footer
</div>
</template>
Vue router layouts
Finally, Let’s create router groups and add a layout for each one.
import { createRouter, createWebHistory } from 'vue-router'
import Home from '/src/views/Home.vue'
import About from '/src/views/About.vue'
import DefaultLayout from '/src/layouts/DefaultLayout.vue'
import AboutLayout from '/src/layouts/AboutLayout.vue'
const routes = [
{
path:'/',
name:'Public',
component:DefaultLayout,
redirect: '/',
children:[
{
path:'/',
name:'Home',
component:Home
}
]
},
{
path:'/page',
name:'AboutPage',
component:AboutLayout,
redirect: '/page',
children:[
{
path:'/page/about',
name:'About',
component:About
}
]
},
]
const router = createRouter({
history: createWebHistory(),
routes,
})
export default router
Here we have two groups of routes one named “Public” and the other “AboutPage”. The main component is the layout and all the pages that extend the layout will be in the children
array. Now you can run the server and test.