1

We have been using Vue.js at my company for the last few months and we're really liking it! We are using Element UI for the UI and vue-router for routing. Based on the structure of our data, we nest our routes several layers deep. It looks something like this:

App -> 
    Line ->
        Type ->
            Component1
            Component2
            Component3

Our designer would like to be able to control layouts on a per-page basis, even all the way down inside of Component*. For instance, in Component1 there may be a layout with a sidebar and footer and in Component2 there would be no sidebar but the footer would be hidden.

We've found this complicated based on the nested structure. Instead of components showing up as distinct blocks on a page they are nested inside of each other. We could un-nest each Vue route, but then we run the risk of duplicating logic through a lot of the pages that are at the same level.

What's are some good ways to handle layouts in a nested structure such as this?

2
  • Have you looked into the concept of slots and whether or not they would be appropriate for your use case? Commented Dec 7, 2017 at 20:36
  • Like the above said, slots may work. Alternatively, you can also pass multiple components to the route that you define in order to control which components appear in the page. Commented Dec 7, 2017 at 21:36

1 Answer 1

2

It sounds like layouts are being specified independently of component build, so you would want to make it as orthogonal as possible.

Additional data can be added to routes in the meta property.

const routes = [
  { 
    path: '/', 
    name: 'Home', 
    component: Home,
    meta: { hiddenFeatures: {sidebar: true, footer: false} }
  },
  ...

On App component, watch for route changes and set visibility flags based on the additional configuration.

export default {
  name: 'app',
  data() {
    return {
      ...
      hiddenFeatures: {}
    };
  },
  watch: {
    '$route': function (route) {
      this.hiddenFeatures = route.meta.hiddenFeatures || {}
    }
  },
}

In the App template, use conditional rendering

<template>
  <div id="app">
    <div class="container-fluid">
      <sidebar v-if="!hiddenFeatures.sidebar"></sidebar>

By getting the logic the right way round, you can avoid having to add properties to every single route, just (e.g) those you want to hide.

Sign up to request clarification or add additional context in comments.

1 Comment

To prevent the possible issue because of the incorrect initial value of hiddenFeatures of data, instead of hiddenFeatures: {} it must be init with hiddenFeatures: this.$route.meta.hiddenFeatures || {}.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.