2
votes

I am trying to get a Vuetify navigation drawer to open up on click of a hamburger menu. So far I've got an app component with two child components, <navbar/> and <drawer/>.

<template>
   <v-app>
     <navbar/>
     <drawer v-show='showSideBar'/>
     <router-view></router-view>
   </v-app>
</template>

<script>
  import { mapState, mapActions, mapGetters } from 'vuex';
  import Navbar from '@/_components/Navbar/Navbar';
  import Drawer from '@/_components/Drawer/Drawer';

  export default {
    name: "app",
    computed: {  
      ...mapGetters('navbar', {
        showSideBar: 'g_sideBarOpen',
      })
    },
    components: {
      Navbar,
      Drawer,
    }
  };
</script>

Navbar.vue:

<template>
    ...
    <v-toolbar-side-icon 
      :ripple='false'
      @click.stop='toggleSideBar'
    ></v-toolbar-side-icon>
</template>

<script>
  import { mapState, mapActions } from 'vuex';

  export default {
    data: () => ({
      items: [
        { 
          title: 'Profile',
          url  : '/profile',
        },
        { 
          title: 'Logout',
          url  : '/login',
        },
      ],
    }),
    components: {
      Logo,
    },
    computed: {
      ...mapState({
        account: state => state.account,
      }),  
    },
    methods: {
      ...mapActions('navbar', [
        'toggleSideBar',
      ]),
    }
  }
</script>

Drawer.vue:

<template>
  <v-navigation-drawer absolute temporary>
    <v-list class="pa-1">
      <v-list-tile avatar>
        <v-list-tile-avatar>
          <img src="https://randomuser.me/api/portraits/men/85.jpg">
        </v-list-tile-avatar>

        <v-list-tile-content>
          <v-list-tile-title>John Leider</v-list-tile-title>
        </v-list-tile-content>
      </v-list-tile>
    </v-list>

    <v-list class="pt-0" dense>
      <v-divider></v-divider>

      <v-list-tile v-for="item in items" :key="item.title">
        <v-list-tile-action>
          <v-icon>{{ item.icon }}</v-icon>
        </v-list-tile-action>

        <v-list-tile-content>
          <v-list-tile-title>{{ item.title }}</v-list-tile-title>
        </v-list-tile-content>
      </v-list-tile>
    </v-list>
  </v-navigation-drawer>
</template>

<script>
  export default {
    data: () => ({
      items: [
        {
          title: "Profile",
          url: "/profile"
        },
        {
          title: "Logout",
          url: "/login"
        }
      ]
    })
  };
</script>

My navbar.module.js is as follows:

const state = {
  sideBarOpen: false,
};

const getters = {
  g_sideBarOpen(state) {
    return state.sideBarOpen
  }
};

const actions = {
  toggleSideBar({ commit }) {
    commit('toggleSideBar');
  },
};

const mutations = {
  toggleSideBar(state) {
    state.sideBarOpen = !state.sideBarOpen;
  }
};

export const navbar = {
  namespaced: true,
  state,
  actions,
  getters,
  mutations,
};

Looking at the Vue/Vuex devtools, I can tell that the Vuex portion of things is working correctly and state correctly updates to reflect that sideBarOpen is either false or true.

When I click the hamburger and verify that sideBarOpen is true, and inspect the DOM, it appears to me that the transform: translateX(-300px) style doesn't change at all, and in fact when I remove that property I can see the drawer move correctly into view.

vuetify drawer

I can't figure out for the life of me what the issue is, but I feel like it's something simple. Has anybody run into a similar issue?

*Edited to include Navbar.vue

1
I'm not too familiar with vuetify.js, but i don't see how v-show affects the transform css property of the drawer component. v-show simply changes whether or not a component is displayed (using the css display property) and is a directive available to all components. Are you sure you are using the correct prop for drawer?Thomas Kilkelly
Great point, I think I saw that on a tutorial somewhere. The Vuetify examples show it with v-model="" and their navigation-drawer api shows the prop "value" as what controls visibility. I've definitely tried both of those routes though and none seem to appear for me for whatever reason.J. Jackson
Well...what does your Drawer component look like? Vuetify only seems to have v-navigation-drawerThomas Kilkelly
I've updated my post with Drawer.vueJ. Jackson

1 Answers

1
votes

Try v-model='showSideBar' instead of 'v-show'. The prop value is actually tied to the v-model directive. v-show would work if your drawer wasn't temporary, but temporary drawers will have its transform CSS value set to your negative value to 'hide' it from view until you display the drawer by setting its value prop to true.

Play around with this and change the temporary directive with permanent, v-show with v-model and the thing data variable.

Note, you need to set v-model within v-navigation-drawer, not drawer. It's up to you how you pass the value of showSideBar, but just note that the Drawer component itself isn't using v-model in any way but v-navigation-drawer is.