# Layout

There are several ways to organize an application developed with Builderall Vue UI. But they must all have a BUISidebar, BUINavbar and BUIContainer at the same hierarchical level and sharing the same variable sidebar-state. Inside the BUIContainer is the place where your pages should be built.

<template>
  <div>
    <bui-sidebar
      :menus="menus"
      :menus-bottom="menus"
      :sidebar-state="sidebarState"
    />

    <bui-navbar
      :sidebar-state="sidebarState"
      logo="https://booking.builderall.com/images/images/meta/logo.png"
      @toggle-sidebar="toggleSidebar"
    />

    <bui-container :sidebar-state="sidebarState">
      <bui-page
        title="Dashboard"
        subtitle="Welcome to a Builderall application!"
      >
        <template #page-header-right>
          <b-button
            variant="primary"
            class="ml-auto"
          >
            <bui-icon
              name="plus"
              variant="white"
              :size="18"
            />
            New calendar
          </b-button>
        </template>
        <bui-alert
          index="alert-01"
          content="Welcome!"
        />
      </bui-page>
    </bui-container>
  </div>
</template>

<script>
export default {
  data () {
    return {
      sidebarState: 'expanded',
      menus: [{ title: 'Item', icon: 'gear', href: '#' }]
    }
  },
  methods: {
    toggleSidebar (state) {
      this.sidebarState = state
    }
  }
}
</script>

If your application uses the Vue router (opens new window), the default slot of BUIContainer is the perfect place to insert <router-view>






 





<template>
  <div>
    <bui-sidebar ... />
    <bui-navbar ... />
    <bui-container ... >
      <router-view />
    </bui-container>
  </div>
</template>

# Basic example with localStorage

For the status of the sidebar to be remembered when reloading the page, or to exit and open the application again, we can use localStorage:






















 










 





 





<template>
  <div>
    <bui-sidebar
      :menus="menus"
      :menus-bottom="menus"
      :sidebar-state="sidebarState"
    />

    <bui-navbar
      :sidebar-state="sidebarState"
      logo="https://booking.builderall.com/images/images/meta/logo.png"
      @toggle-sidebar="toggleSidebar"
    />

    <bui-container :sidebar-state="sidebarState">
      <router-view />
    </bui-container>
  </div>
</template>

<script>
const sidebarStateKey = 'bui_store_sidebar_state'

export default {
  data: () => {
    return {
      sidebarState: 'expanded',
      menus: [{ title: 'Item', icon: 'gear', href: '#' }]
    }
  },

  mounted () {
    this.sidebarState = localStorage.getItem(sidebarStateKey) || 'expanded'
  },

  methods: {
    toggleSidebar (state) {
      this.sidebarState = state
      localStorage.setItem(sidebarStateKey, state)
    }
  }
}
</script>

# Using Vuex

For better code organization, you may want to store the sidebar state in a Vuex store (opens new window), mapping sidebar-state as a state variable and transforming toggleSidebar in an mutation.

store.js

 



 


 






const sidebarStateKey = "bui_store_sidebar_state";

export default new Vuex.Store({
  state: {
    sidebarState: localStorage.getItem(sidebarStateKey) || "expanded"
  },
  mutations: {
    toggleSidebar(state, payload) {
      localStorage.setItem(sidebarStateKey, payload);
      state.sidebarState = payload
    }
  },
})

TheNavbar.vue


 


 




export default {
  computed: mapState(["sidebarState"]),
  methods: {
    toggleSidebar(state) {
      this.$store.commit("toggleSidebar", state);
    },
  },
};

# File structure

There is no problem in keeping all layout components in a single file (bui-sidebar, bui-navbar e bui-container). However, it is a good practice to keep each component in a separate file, since each has its properties and events that require implementation of particular methods, in addition to allowing the scalability of the system. So a good approach for this would be to use a file structure like this:

├── App.vue
├── components/layout
│   ├── TheNavbar.vue
│   ├── TheSidebar.vue
├── views
│   ├── Home.vue
│   ├── About.vue

Thus:

  • Each view must have a bui-page as root element;
  • The TheNavbar file must have only the component <bui-navbar> with all the props and definition of the logout methods, language change and change of the state of the sidebar;
  • The TheSidebar file must have only the component <bui-sidebar>, with the definition of the menus, user data and all the customizations of the component slots;
  • The App.vue file must group all these components and provide a <router-view> slot for the views.

App.vue

<template>
	<the-sidebar/>
	<the-navbar/>
	<bui-container>
		<router-view/>
	</bui-container>
</template>

# Using a Layout file

Sometimes you may not use Vue Router (opens new window) to manage your application's routes and therefore you don't have a router-view component to inject pages into it. Examples of this are using Vue in conjunction with Laravel (opens new window) or InertiaJs (opens new window). In such cases, a good option is the creation of layout files: you only provide a slot instead of the router-view and inherit this component in all pages of the application

MyLayout.vue





 



<template>
	<the-sidebar/>
	<the-navbar/>
	<bui-container>
		<slot/>
	</bui-container>
</template>

Home.vue


 



 


<template>
	<my-layout>
		<bui-page title="Dashboard" subtitle="Working!">
			Home.vue
		</bui-page>
	</my-layout>
</template>