vuejs application with different layouts (e.g. login layout, page layout, signup etc.) vuejs application with different layouts (e.g. login layout, page layout, signup etc.) vue.js vue.js

vuejs application with different layouts (e.g. login layout, page layout, signup etc.)


I think I found a solution. The approach has App.vue containing only <router-view></router-view> and then including different components that represent layout (if needed, containing <router-view> and subroutes). I found a project using it in that way here.

I think it keeps things more clean and organised. IMHO, hiding all elements which define layout structure (all the divs) would be too messy - especially for bigger apps.


A nice solution for this is using slots

First create your "layout component"

src/components/layouts/basic.vue

<template>  <div class="basic-layout">    <header>[Company logo]</header>    <hr>    <slot/>    <hr>    <footer>      Made with ❤ at Acme    </footer>  </div></template>

Then use it in another component:

<template>  <layout-basic>    <p>Hello world!</p>  </layout-basic></template><script>  import LayoutBasic from '@/components/layouts/basic'  export default {    components: {      LayoutBasic    }  }</script>

"Hello world" will appear where the <slot/> tag is.

You can also have multiple slots with names, see the complete docs.


I find another solution by using router meta. I just have a few components need another layout.

I added a plainLayout meta key in src/router/index.js.

export default new Router({  mode: 'history',  linkExactActiveClass: 'app-head-menu--active',  routes: [    {      path: '/',      component: Features,    },    {      path: '/comics/:id',      component: Comic,      props: true,    },    {      path: '/comics/:comic_id/:chapter_index',      component: Chapter,      props: true,      meta: {        plainLayout: true,      },    },  ],});

Then render layout conditionally with playLayout in src/App.vue.

<template>  <div>    <div v-if="!$route.meta.plainLayout">      <div class="app-head">      </div>      <div class="app-content">        <router-view/>      </div>    </div>    <div v-if="$route.meta.plainLayout">      <router-view/>    </div>  </div></template><script>export default {  name: 'app',};</script>

See a demo project here.