# 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>