Vue Responsive Menu

By ukmodak | May 18th 2022 09:26:00 AM | viewed 16 times
<template>
<header>
<div class="mobileOption">
<div class="ukMobileButton" type="button" @click="toggleMobile">
<div class="line"></div>
<div class="line"></div>
<div class="line"></div>
</div>
</div>


<nav class="mobile" :class="mobileOnOff? 'active':'inactive'">
<div class="menu-item" ><router-link :to="{name:'ad_dashboard'}">Home</router-link></div>

<span v-if="menuData" class="span">          
<span v-for="root in menuData.root" class="span">
<span v-if="root.has_tree=='yes'" class="span">

<div class="menu-item" @click.self="checkOnOf(root.root)" :key="Math.random()*10">
{{root.root}} <svg height="28pt" preserveAspectRatio="xMidYMid meet" viewBox="0 0 49 28" width="49pt" xmlns="http://www.w3.org/2000/svg" class="vnb__menu-options__option__arrow"><title>Toggle Arrow 

<div class="sub-menu" v-if="(selected==root.root? true:false) && (isOpenLavelOne)">
<span v-for="menu in menuData.menu" class="span">
<span v-if="menu[root.root]">

<div class="menu-item"> <router-link :to= "{name:menu.route_name}">{{menu[root.root]}}</router-link></div>
</span>
</span>

<span v-for="tree in menuData.tree" class="span">
<div class="menu-item" @click="checkSubOnOf(tree[root.root])" :key="Math.random()*10">
{{tree[root.root]}}<svg height="28pt" preserveAspectRatio="xMidYMid meet" viewBox="0 0 49 28" width="49pt" xmlns="http://www.w3.org/2000/svg" class="vnb__menu-options__option__arrow"><title>Toggle Arrow</title> </path></svg>

<div class="sub-sub-menu" v-if="(subselected == tree[root.root]? true:false) && (isOpenLavelTwo ==true)"> 
<span v-for="treemenu in menuData.menu" class="span">
<span v-if="treemenu[tree[root.root]]" class="span">

<div class="menu-item"> <router-link :to= "{name:treemenu.route_name}">{{treemenu[tree[root.root]]}}</router-link></div>
</span>
</span>
</div>
</div>
</span>

</div>
</div>
</span>

<span v-else class="span">
<div class="menu-item" @click.self="checkOnOf(root.root)" :key="Math.random()*10">
{{root.root}} <svg height="28pt" preserveAspectRatio="xMidYMid meet" viewBox="0 0 49 28" width="49pt" xmlns="http://www.w3.org/2000/svg" class="vnb__menu-options__option__arrow"><title>Toggle Arrow</title> </path></svg>

<div class="sub-menu" v-if="(selected==root.root? true:false) && (isOpenLavelOne)">
<span v-for="menu in menuData.menu" class="span">
<span v-if="menu[root.root]">

<div class="menu-item"> <router-link :to= "{name:menu.route_name}">{{menu[root.root]}}</router-link></div>
</span>
</span>
</div>
</div>
</span>
                      
                      
</span>
</span>
          
    
</nav>


    
</header>
     
</template>

<script>

import "bootstrap/dist/css/bootstrap.min.css";
import axios from 'axios';
import manualConfig from "../config/configManual";

  export default {
      data:()=>({
         isOpenLavelOne:false,
         isOpenLavelTwo:false,
         selected:'',
         subselected:'',
         mobileOnOff:false,
         userData:'',
         menuData:'',
         menuLabelOne:null,
      }),
      components: {

       },

      created(){
       this.menuData = (localStorage.getItem('menuData'))? JSON.parse(localStorage.getItem('menuData')):'';
        this.userData = (localStorage.getItem('userData'))? JSON.parse(localStorage.getItem('userData')):'' ;
        //this.getmenu(this.userData,this.menuData);
      },
      mounted() {

      },
     
    methods:{
        checkOnOf(value){
         
         this.selected = value;
         this.isOpenLavelOne = ! this.isOpenLavelOne;
        },

      checkSubOnOf(value){
         this.subselected = value;
         this.isOpenLavelTwo = !this.isOpenLavelTwo;
        },
         toggleMobile(){
             return this.mobileOnOff = ! this.mobileOnOff;
         },
         getmenu(userData,menuData){

             if(menuData =='' && userData.role_id){
                  
                     axios.post(manualConfig.sitePath+"/api/user_menu",
                          {
                          role_id:userData.role_id,
                          'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content,
                          })
                           .then((response)=>{
                              
                                  if(JSON.stringify(response.data)){
                                      localStorage.setItem('menuData',JSON.stringify(response.data));
                                   }
                             })
                             .catch(error => {
                                    console.log(error)
                                    alert("menu loading error");
                              })
                       
                }
         }         
     },
    computed: {
      
    }
      
  };
</script>

<style scoped>

@media (min-width: 756px) and (max-width: 2000px){

span {
 float:left;
}

   .mobileOption{
    display:none;
  }
 header{
  padding:0px;
  background-color:#F9F9F9;
  width:100%;
 }
 nav{
   display:flex;
   align-items:center;
   justify-content:center;
  }


  nav .menu-item{
    color:#000;
    padding:10px 20px;
    position:relative;
    text-align:center;
    border-bottom:3px solid transparent;
    transition:0.4s;
   }



 nav .menu-item.active,
 nav .menu-item:hover
{
   background-color:#A6A6A6;
   border-bottom-color:#ff5858;
   }

nav .menu-item a{
  color:inherit;
  text-decoration:none;
 }

nav .menu-item svg{

   /*
    width:10px;
    margin-left:10px;
   */

    width: 10px;
    margin-top: -7px;
    float: right;
    margin-right: -17px;
    margin-left: 16px;

 }

nav .menu-item .sub-menu{
    position:absolute;
    background-color:#F9F9F9;
    top:calc(100% + 2px);
    left:calc(190px - 95px);
    transform:translateX(-50%);
    width:max-content;
    border-radius:0px 0px 16px 16px;
    z-index:99;
    transition:.4s;
    padding:0px 0px;
    width: 190px;
    float: left;
 }

nav .sub-menu .sub-sub-menu{
    position: absolute;
    background-color: #F9F9F9;
    top: calc(-6% + 2px);
    left: 150%;
    transform: translateX(-50%);
    width: -webkit-max-content;
    width: -moz-max-content;
    width: max-content;
    border-radius: 0px 0px 16px 16px;
    z-index: 99;
    transition: .4s;
    padding: 0px 0px;
    width: 190px;
    float: right;
 }



nav .sub-menu .menu-item
{
   width:190px;
}


nav .sub-menu .sub-sub-menu .menu-item{
    color:#000;
    padding:10px 20px;
    position:relative;
    text-align:center;
    border-bottom:3px solid transparent;
    transition:0.4s;
    width:190px;
   }





nav .sub-menu .menu-item.active,
nav .sub-menu .menu-item:hover
{
   background-color:#A6A6A6;
   border-bottom-color:#ff5858;
   width:190px;
}


nav .sub-menu .sub-sub-menu .menu-item.active,
nav .sub-menu .sub-sub-menu .menu-item:hover
{
   background-color:#A6A6A6;
   border-bottom-color:#ff5858;
   width:190px;
}


nav .sub-menu .sub-sub-menu .menu-item a{
  color:inherit;
  text-decoration:none;
 }


nav .sub-menu .menu-item svg{
  width:10px;
  margin-left:10px;
 }

nav .sub-menu .sub-sub-menu .menu-item svg{
  width:10px;
  margin-left:10px;
 }


  .fade-enter-active,
  .fade-enter-leave{
      transition:all .5s ease-out;
   }

   .fade-enter,
  .fade-leave-to{
     opacity:0;
   }
}

@media (min-width: 200px) and (max-width: 755px){

span {
 float:left;
}

   .mobileOption{
    display:block;
  }

 .ukMobileButton{
     width:30px;
     height:30px;
     //background-color:#000;
     //border:1px solid blue;
     background:transparent;
     float: right;
     margin: 10px 40px;
    
  }

.ukMobileButton .line{
   border-top:3px solid gray;
   float:left;
   width:100%;
   height:8px;
}



 header{
  padding:0px;
  background-color:#F9F9F9;
  width:100%;
 }
 nav{
   float:left;
   align-items:center;
   justify-content:center;
  }

  nav.mobile{
   display:none;
   width:150px;
   margin:0px;
   padding:0px;
  }

  nav.mobile.active{
   display:block;
   } 

  nav .menu-item{
    color:#000;
    padding:10px 20px;
    position:relative;
    text-align:center;
    border-bottom:3px solid transparent;
    display:block;
    transition:0.4s;
    text-align: left;
    width:150px;
    padding:0px 10px;
    margin:0px;

   }



        nav .menu-item.active,
         nav .menu-item:hover
        {
           background-color:#A6A6A6;
           border-bottom-color:#ff5858;
           display: block;
           }

         nav .sub-menu .menu-item.active,
         nav .sub-menu .menu-item:hover
        {
           background-color:#A6A6A6;
           border-bottom-color:#ff5858;
           display: block;
           }


         nav .sub-menu .sub-sub-menu .menu-item.active,
         nav .sub-menu .sub-sub-menu .menu-item:hover
        {
           background-color:#A6A6A6;
           border-bottom-color:#ff5858;
           display: block;
           }
    


 

nav .menu-item a{
  color:inherit;
  text-decoration:none;
  float:left;
 }

nav .menu-item svg{
  width:10px;
  margin-left:10px;
 }

nav .menu-item .sub-menu{
    position:relative;
    background:transparent;
    transform:translateX(9%);
    width:max-content;
    border-radius:0px 0px 16px 16px;
    z-index:99;
    transition:.4s;
    width:150px;
    padding:0px 5px;
    margin:0px;
 }

  .fade-enter-active,
  .fade-enter-leave{
      transition:all .5s ease-out;
   }

   .fade-enter,
  .fade-leave-to{
     opacity:0;
   }
}

@media (hover:hover) {

        nav .menu-item.active,
         nav .menu-item:hover
        {
           background-color:#A6A6A6;
           border-bottom-color:#ff5858;
           display: block;
           }

         nav .sub-menu .menu-item.active,
         nav .sub-menu .menu-item:hover
        {
           background-color:#A6A6A6;
           border-bottom-color:#ff5858;
           display: block;
           }


         nav .sub-menu .sub-sub-menu .menu-item.active,
         nav .sub-menu .sub-sub-menu .menu-item:hover
        {
           background-color:#A6A6A6;
           border-bottom-color:#ff5858;
           display: block;
           }
    
   }
  
</style>
bONEandALL
Visitor

Total : 4243

Today :39

Today Visit Country :

  • United States