Search code examples
vue.jsvuejs2dropdown

Trying to understand a better way to code my drop-down menus in vue


I am making the jump from jQuery/WordPress to Vue and I am really loving it so far but very basic things can confuse the hell out of me. I am working on a project and I'm trying to do the coding work myself (not copy/paste code into my app) so I can force myself to learn it. I have been working on a dropdown menu system and got it working, but I know it's sloppy.

I was having trouble passing variables down to the methods section, so I couldn't seem to make my functions dynamic. So I had to repeat a lot of code to get it to work. I know there is a better way of doing this, I just don't understand what Vue wants from me. I kept getting 'variable is defined but not used' errors when I tried to pass information. I don't have the broken code anymore so I can't show that off, but I do have my working code.

I am hoping someone can critique my shit code and help me understand a more sleek way of doing this.

<template>
  <div>
    <div id="nav">
      <nav>
        <ul>
          <li>
            <a class="navButton" @click.prevent="mapsDrop">Maps <i class="fas fa-layer-group"></i></a>
            <transition name="slide-fade">
              <div class="dropDown" v-show="isMapsOpen">
                Drop Down Menu
              </div>
            </transition>
          </li>
          <li>
            <a class="navButton" @click.prevent="createDrop">Create <i class="fas fa-plus-circle"></i></a>
            <transition name="slide-fade">
              <div class="dropDown" v-show="isCreateOpen">
                Drop Down Menu
              </div>
            </transition>
          </li>
          <li>
            <a class="circle" @click.prevent="notificationsDrop"><i class="fas fa-bell"></i></a>
            <transition name="slide-fade">
              <div class="dropDown" v-show="isNotificationsOpen">
                Notofications
              </div>
            </transition>
          </li>
        </ul>
      </nav>
    </div>
  </div>
</template>
<script>
export default {
  data() {
    return{
      isMapsOpen: false,
      isCreateOpen: false,
      isNotificationsOpen: false
    }
  },
  methods: {
    toggle() {
      mutations.toggleNav();
    },
    mapsDrop() {
      this.isMapsOpen = !this.isMapsOpen
      if(this.isNotificationsOpen){
        this.isNotificationsOpen = !this.isNotificationsOpen
      }
      if(this.isCreateOpen){
        this.isCreateOpen = !this.isCreateOpen
      }
    },
    createDrop() {
     this.isCreateOpen = !this.isCreateOpen
      if(this.isNotificationsOpen){
        this.isNotificationsOpen = !this.isNotificationsOpen
      }
      if(this.isMapsOpen){
        this.isMapsOpen = !this.isMapsOpen
      }
    },
    notificationsDrop() {
     this.isNotificationsOpen = !this.isNotificationsOpen
      if(this.isCreateOpen){
        this.isCreateOpen = !this.isCreateOpen
      }
      if(this.isMapsOpen){
        this.isMapsOpen = !this.isMapsOpen
      }
    }
  }
};
</script>

I'll repeat, this all works. I couldn't figure out how to get it to run in snippet mode, and I've stripped out some of the other parts so you don't have to dig through it.. I shouldn't have to create functions for each of my menus, right?

Thanks in advance.


Solution

  • Try having one data value and toggling with just that:

    new Vue({
      el: "#app",
      data() {
        return{
          toggle: ""
        }
      },
    })
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.0-2/css/all.min.css" rel="stylesheet"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
    
    <div id="app">
        <div id="nav">
          <nav>
            <ul>
              <li>
                <a class="navButton" @click.prevent="toggle = 'maps'">Maps <i class="fas fa-layer-group"></i></a>
                <transition name="slide-fade">
                  <div class="dropDown" v-if="toggle === 'maps'">
                    Drop Down Menu
                  </div>
                </transition>
              </li>
              <li>
                <a class="navButton" @click.prevent="toggle = 'create'">Create <i class="fas fa-plus-circle"></i></a>
                <transition name="slide-fade">
                  <div class="dropDown" v-if="toggle === 'create'">
                    Drop Down Menu
                  </div>
                </transition>
              </li>
              <li>
                <a class="circle" @click.prevent="toggle = 'notifications'"><i class="fas fa-bell"></i></a>
                <transition name="slide-fade">
                  <div class="dropDown" v-if="toggle === 'notifications'">
                    Notifications
                  </div>
                </transition>
              </li>
            </ul>
          </nav>
        </div>
    </div>

    Insert a unique value for each dropdown and then use v-if to determine if it contains the correct value.