I wish to build my web application with the Holy Grail layout, with just one sidebar, and no footer. The sidebar will be used as a navigation bar, as well as for holding interactive option for content that will be displayed in the center of the layout, depending on the currently chose link. Meaning that, when choosing a link to navigate to in the navigation bar, it will affect the displayed content in the sidebar for custom interaction options, and the main content in the center.
For achieving this I have came up with couple of approaches:
Layout
component creating our layout, with Header
and Navbar
for sub-components.router-view
component to display the current path componentLayout
component and inject the appropriate custom navigation options, and main content using slots.Layout
component:
<template>
<div class="app-layout">
<header-component></header-component>
<div class="main">
<navbar-component>
<slot name="navigation-menu"></slot>
</navbar-component>
<main>
<slot name="main-content"></slot>
</main>
</div>
</div>
</template>
<script>
import Header from './Header.vue';
import Navbar from './Navbar.vue';
export default {
name: 'Layout',
components: {
'header-component': Header,
'navbar-component': Navbar
}
};
</script>
<style lang="sass" rel="stylesheet/scss" scoped>
some styling to achieve our layout for the present tags in the template
</style>
Header
component:
<template>
<header v-once class="header">
<router-link to="/">
Brand
</router-link>
</header>
</template>
<script>
export default {
name: 'Header'
};
</script>
<style lang="sass" rel="stylesheet/scss" scoped>
some styling to achieve our layout for the present tags in the template
</style>
Navbar
component:
<template>
<nav class="navigation">
<div class="links">
// iterate on some property of this component, and create a list of links
</div>
<div class="menu">
<slot name="navigation-menu"></slot>
</div>
</nav>
</template>
<script>
export default {
name: 'Navbar'
};
</script>
<style lang="sass" rel="stylesheet/scss" scoped>
some styling to achieve our layout for the present tags in the template
</style>
Vue instance with routing:
import link1Component from './components/Link1ComponentUsingLayout.vue';
import link2Component from './components/Link2ComponentUsingLayout.vue';
import link3Component from './components/Link3ComponentUsingLayout.vue';
const router = new VueRouter({
mode: 'history',
routes: [
{
path: '/',
redirect: '/link1'
},
{
path: '/link1',
name: 'link1',
component: Link1ComponentUsingLayout
},
{
path: '/link2',
name: 'link2',
component: Link2ComponentUsingLayout
},
{
path: '/link3',
name: 'link3',
component: Link3ComponentUsingLayout
}
]
});
export default new Vue({
el: '#app',
router,
render: h => h('router-view')
});
router-view
component to display the current path componentrouter-view
componentsNow, I was wondering which approach would be the best and why? Also I would like to hear new approaches if you have any, and explanation for why they're better.
I don't have an explanation if this would be better, but I would like to add another approach I've previously used.
Assume that your project needs multiple layouts such as a layout for the admin, a separate one for the end user, and so on. Although this doesn't seem to really fit your use case, you could consider it an addition.
Layout.vue
Your Layout will contain the components that will persist on any page under it.
<template>
<div>
<header-component />
<div class="main">
<navbar-component />
<main>
<!-- your child routes here -->
<router-view />
</main>
</div>
</div>
</template>
router.js
In your routes, you nest your components or views under Layout.vue
like so:
routes: [
{
path: '',
component: Layout,
// child routes now have the style of Layout
children: [
{
path: '/page1',
name: 'Page1Name',
component: Page1
},
// ...
]
}
]
Child components of Layout.vue
are shown in its <router-view />
.
NavComponent.vue
<template>
<nav class="navigation">
<!-- links and other stuff -->
<!-- your custom interactive options below -->
<div v-if="isInRoutes('Page1Name')">
<!-- div or some component for Page1 -->
</div>
</nav>
</template>
wherein
isInRoutes
method checks forthis.$route.name
or it can be more complex than that.
Your App.vue
(the one you'll render with h(App)
) will also contain a <router-view />
of its own so it will show the layouts.
App.vue
<template>
<div>
<router-view />
</div>
</template>
With this approach, you can create multiple layouts and nest your components under a particular layout using your routes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With