Anyway, here’s how to create a multiple layout system with Vue and Vue-router

Futari Boy - developer & indie hacker
ITNEXT
Published in
4 min readMay 31, 2018

--

Have you ever had different layouts depending on your content?

Let me explain, let’s say you create a blog. You want the home & about page not to have a sidebar, but all the other pages to have one. You see the idea?

In itself, it’s not complicated you will tell me, just create a sidebar component and import it into every page component where you need it.

Okay, but it still sucks to import this sidebar all the time and write it down, right? What if there’s an easier way? Indicate it in the router for example?

Here’s how to use route-view to create a multiple layout system

First of all, why do it with Vue-router?

The router is where we define the pages of our site, so why not specify which layout we want per page in it?

Let’s start by creating our project with vue-cli 3.

Let’s create our layouts first. It will be components with no logic, just HTML / CSS that accepts a slot, the content to inject.
(I used bulma CSS).

The default layout with sidebar
The layout without sidebar that is used on some pages

Okay cool, we have our layouts. Let’s add our pages to the router.

We add our pages from a specific folder to the routers

As you can see, I added a meta key for the Home & About page.
In Vue-router, instead of creating keys at the root, prefere the meta key which is made to set data related to each route.
https://router.vuejs.org/guide/advanced/meta.html

How do we do it now? Let’s import layouts globally

Now that we have our routes, pages and layouts, let’s mix it all in App.vue and import the layouts globally into main.js.

Layouts are imported globally with Vue.component( …)

You noticed, didn’t you? I added a “-layout” suffix to have a name with two words or more and also because it is more precise.

But! But! In our meta we did not put the “-layout”, how do we do?

This is where the magic appears, first we will load / use our layouts on the fly depending on the current route.

Vue-router is powerful and gives us access in each component to $route which represents the current route. We will check the meta on it to know which layout to load, and also define a default layout.

We load/use our layouts dynamically with “component is” and $route

The steps

  1. We define a constant which contains the default layout to load
  2. We create a computed property based on $route so that the layout changes dynamically when we change URL / route
  3. When meta.layout contains undefined, we fallback to the default layout
  4. The result of the condition is concatenated with what ? “-layout
  5. We use the special component <component is=“…”> which allows to use a component dynamically with the prop is which takes as value the name of the component to display

Conclusion

When you arrive on a route that does not have a meta with a layout key, the code will generate “default-layout”, otherwise, if there is a layout key, it gives “value of the key — layout”, so in our case “no-sidebar-layout”.

Once this value is calculated in computed, the template with component and prop is, will take care of the rest.

/!\ Important: do not forget to give the page to display thanks to :
<router-view /> which is used by the router to display the route.

Are there more complex cases where you could use this same system? Yes
Simple examples :

  • having a fullscreen Ad Banner around the content
  • having different header / nav / footer depending on the user role
  • having a 3 grids design : fluid, 2 columns & 3 columns

That’s is where dynamically loading a LayoutComp is useful, you can create one component per layout, that component holds the visual complexity and only takes the content (<slot>) as parameter.

To know more about vue-router :
https://router.vuejs.org/

To understand <compoent is=“ ”><component> :
https://vuejs.org/v2/guide/components.html#Dynamic-Components

To see the code in action :
https://darkylmnx.github.io/Layout-system-with-vue-and-vue-router/

To inspect the complete source code on github
https://github.com/darkylmnx/Layout-system-with-vue-and-vue-router

If you appreciated this story, don’t hesitate to clap & share this article.

PS:
If you like traveling or like amazing landscapes : https://goo.gl/paFUwK
If you want to discover some RAP other than US : https://goo.gl/4C4suQ
If you are more animes & mangas : https://goo.gl/GZ2FtJ

PS 2: If you want to learn how to create advanced components, checkout my course: https://courses.maisonfutari.com/mastering-vue-components-creating-a-ui-library-from-scratch?coupon=MEDIUM

There’s a 50% discount because you’re coming from this story.

--

--

Developer, nomad, SaaS & micro-SaaS founder 👋 #indiehacker 👨‍💻 #freelance 🇯🇵 #anime #japan