/components/Menu/Burger.vue
<template>
<div id="burger" :class="{ 'active' : isBurgerActive }" @click.prevent="toggle">
<slot>
<div class="container-fluid">
<div class="row">
<button type="button" class="burger-button" title="Menu">
<span class="hidden">Toggle menu</span>
<span class="burger-bar burger-bar--1"></span>
<span class="burger-bar burger-bar--2"></span>
<span class="burger-bar burger-bar--3"></span>
</button>
</div>
</div>
</slot>
</div>
</template>
<script>
import { store, mutations } from '@/store';
export default {
computed: {
isBurgerActive() {
return store.isNavOpen;
}
},
methods: {
toggle() {
mutations.toggleNav();
}
}
};
</script>
<style>
.hidden {
visibility: hidden;
}
button {
cursor: pointer;
}
/* remove blue outline */
button:focus {
outline: 0;
}
.burger-button {
position: relative;
height: 45px;
width: 45px;
display: block;
z-index: 999;
border: 2px solid #F56905;
border-radius: 10px;
background-color: transparent;
pointer-events: all;
transition: transform 0.6s cubic-bezier(0.165, 0.84, 0.44, 1);
}
.burger-bar {
background-color: #8cae42;
position: absolute;
top: 50%;
right: 6px;
left: 6px;
height: 3px;
width: auto;
margin-top: -1px;
transition: transform 0.6s cubic-bezier(0.165, 0.84, 0.44, 1),
opacity 0.3s cubic-bezier(0.165, 0.84, 0.44, 1),
background-color 0.6s cubic-bezier(0.165, 0.84, 0.44, 1);
}
.burger-bar--1 {
-webkit-transform: translateY(-6px);
transform: translateY(-6px);
}
.burger-bar--2 {
transform-origin: 100% 50%;
/*transform: scaleX(0.8);*/
}
.burger-button:hover .burger-bar--2 {
transform: scaleX(1);
}
.no-touchevents .burger-bar--2:hover {
transform: scaleX(1);
}
.burger-bar--3 {
transform: translateY(6px);
}
#burger.active .burger-button {
transform: rotate(-180deg);
}
#burger.active .burger-bar {
background-color: #fff;
}
#burger.active .burger-bar--1 {
transform: rotate(45deg);
}
#burger.active .burger-bar--2 {
opacity: 0;
}
#burger.active .burger-bar--3 {
transform: rotate(-45deg);
}
.menutext{
margin-bottom: 0;
line-height: 1;
vertical-align: center;
font-weight: bold;
padding-left: 5%;
padding-top: 5%;
font-size: .9em;
margin-top: auto;
margin-bottom: auto;
}
</style>
/components/Menu/Sidebar.vue
<template>
<div class="sidebar">
<div class="sidebar-backdrop" @click="closeSidebarPanel" v-if="isPanelOpen"></div>
<transition name="slide">
<div v-if="isPanelOpen"
class="sidebar-panel">
<slot></slot>
</div>
</transition>
</div>
</template>
<script>
import { store, mutations } from '@/store';
export default {
methods: {
closeSidebarPanel: mutations.toggleNav
},
computed: {
isPanelOpen() {
return store.isNavOpen
}
},
watch: {
'$route' () {
if(store.isNavOpen){
this.closeSidebarPanel();
}
}
}
}
</script>
<style>
.slide-enter-active,
.slide-leave-active
{
transition: transform 0.2s ease;
}
.slide-enter,
.slide-leave-to {
transform: translateX(-100%);
transition: all 150ms ease-in 0s
}
.sidebar-backdrop {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
cursor: pointer;
z-index: 1000;
}
.sidebar-panel {
overflow-y: auto;
position: fixed;
left: 0;
top: 0;
height: 100%;
z-index: 999;
padding: 3rem 20px 2rem 20px;
width: 300px;
z-index: 1001;
}
</style>
/components/Navigation.vue
<template>
<div class="container-fluid">
<div class="row">
<div class="col-lg-4 col-md-12">
<nav class="main-nav">
<Burger></Burger>
<Sidebar>
<ul class="sidebar-panel-nav">
<li>
<router-link to="/">Home</router-link>
</li>
<li>
<router-link to="/about">About</router-link>
</li>
<li>
<router-link to="/contact">Contact Us</router-link>
</li>
</ul>
</Sidebar>
</nav>
</div>
<div class="col-lg-4 col-md-12">
<h1>Hardik Rawat</h1>
</div>
</div>
</div>
</template>
<script>
import Burger from "@/components/Menu/Burger.vue";
import Sidebar from "@/components/Menu/Sidebar.vue";
export default {
name: "Navigation",
components: {
Burger,
Sidebar
},
methods: {
navHome() {
this.$router.push({ name: 'Home' });
},
}
}
</script>
<style>
.main-nav {
display: flex;
justify-content: space-between;
padding: 0.5rem 0.8rem;
}
ul.sidebar-panel-nav {
list-style-type: none;
}
ul.sidebar-panel-nav > li > a {
color: #fff;
text-decoration: none;
font-size: 1.5rem;
display: block;
padding-bottom: 0.5em;
}
</style>
/App.vue
<template>
<div id="app">
<Navigation></Navigation>
<main>
<router-view></router-view>
</main>
</div>
</template>
<script>
import Navigation from "@/components/Navigation";
import { store, mutations } from '@/store'
components: {
Navigation
},
methods: {
closeSidebarPanel: mutations.toggleNav,
},
computed: {
isPanelOpen() {
return store.isNavOpen
}
}
</script>
/store.js
import Vue from 'vue';
export const store = Vue.observable({
isNavOpen: false,
});
export const mutations = {
setIsNavOpen(yesno) {
store.isNavOpen = yesno;
},
toggleNav() {
store.isNavOpen = !store.isNavOpen;
},
};