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:
- Approach 1:
- Have one Vue instance
- Have a
Layoutcomponent creating our layout, withHeaderandNavbarfor sub-components. - Our Vue instance will use a router with a path for each link present in the navigation sidebar
- Our Vue instance will render one
router-viewcomponent to display the current path component - Each route will display a component that its template is using our previously created
Layoutcomponent 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')
});
- Approach 2:
- Have two Vue instances
- Have out layout as a static html inside index.html instead of a component
- Each of the Vue instances will use a router (one for each), with a path for each link present in the navigation bar
- One of the instances will be mounted on the html inside the navigation sidebar in our static html, and one inside the center content area
- Each of the Vue instances will render one
router-viewcomponent to display the current path component
- Approach 3:
- Have one Vue instance
- Our Vue instance will use a router with a path for each link present in the navigation sidebar
- Or Vue instance will template will represent our layout and inside the navigation sidebar, and the center content area we'll have 2
router-viewcomponents - Our Vue instances will render both the navigation sidebar, and the center content are components for the current path
- Approach 4:
- Same as Approach 3, except don't use router and use dynamic components to switch between the navigation sidebar, and the center content area components, whenever a link inside the navigation is clicked.
Now, 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.