DEV Community

Patrick Hanford
Patrick Hanford

Posted on • Edited on

Building a sidebar with Nuxt & Vuex

Vuex Powered Sidebar with NuxtJs

NuxtJs is an awesome framework that takes practical and common structural patterns and creates a highly manageable boilerplate for your VueJS project. I'm personally just getting started with Nuxt, but so far I'm seriously impressed. There's always this routine when starting a new Vue project that Nuxt helps alleviate while also applying some tried-and-true best practices to your project free of charge.

Obviously this makes Nuxt opinionated, for good reason, but that always comes with a bit of a learning curve. In this article I'll walk you through creating a navigation sidebar that's able to be toggled from anywhere in your app through the magic of state.

enter image description here

Starting your Nuxt project

First things first, we'll need to setup our project. You can use a handy script using npx or yarn (dealer's choice).

npx

npx create-nuxt-app <project-name>
Enter fullscreen mode Exit fullscreen mode

yarn

yarn create-nuxt-app <project-name>
Enter fullscreen mode Exit fullscreen mode

You'll be asked a series of questions about your project. If you're unsure how to answer any of these, just go with the defaults! Once you get through that interrogation, you should have a stylish folder structure set for you. Go ahead and start up your dev server and get started.

npm run dev
Enter fullscreen mode Exit fullscreen mode

You should see your test page and be ready to get started!
enter image description here

Build the components

Now I've already been busy, so I have an existing project I'm going to work with. I'll do my best to keep this as arbitrary as possible so you can follow along, but if you have any questions feel free to leave a comment (or DM me on Twitter, I'm always happy to help).

I have 2 relevant components here:

  • NavBar.vue
  • SideBar.vue

Seems redundant aye? Its mainly for layout purposes. The NavBar features the cliche hamburger button which opens my SideBar. You can set this up however you'd like so long as you've got a sidebar, and a button somewhere that summons it.

Here's a glimpse of what I'm working with.
enter image description hereenter image description here

NavBar Template

<template>
  <!-- Top Navbar -->
  <nav
    class="top-navbar flex flex-row align-center p-2 fixed w-full"
    style="z-index: 9001;"
  >
    <!-- Logo Brand -->
    <div class="flex-grow">
      <router-link :to="{ name: 'HomeView' }">
        <img alt="ImStallion Logo" :src="logoIcon" class="w-16 ml-3" />
      </router-link>
    </div>
    <!-- /Logo Brand -->

    <!-- Menu Button -->
    <button class="p-4" @click="toggle">
      <font-awesome-icon :icon="['fas', 'bars']" size="lg"></font-awesome-icon>
    </button>
  </nav>
  <!-- /Top Navbar -->
</template>
Enter fullscreen mode Exit fullscreen mode

SideBar Template

<template>
  <!-- Top Navbar -->
  <nav
    class="top-navbar flex flex-row align-center p-2 fixed w-full"
    style="z-index: 9001;"
  >
    <!-- Logo Brand -->
    <div class="flex-grow">
      <router-link :to="{ name: 'HomeView' }">
        <img alt="ImStallion Logo" :src="logoIcon" class="w-16 ml-3" />
      </router-link>
    </div>
    <!-- /Logo Brand -->

    <!-- Menu Button -->
    <button class="p-4" @click="toggle">
      <font-awesome-icon :icon="['fas', 'bars']" size="lg"></font-awesome-icon>
    </button>
  </nav>
  <!-- /Top Navbar -->
</template>
Enter fullscreen mode Exit fullscreen mode

You'll see on both of these templates we have a @click directive referencing a method called toggle. This will come from a Vuex mapped mutation.

Vuex and Nuxt

Nuxt uses a namespaced modules approach with Vuex meaning you'll have individual js files which represent state. For this example, it'll be drawer.js.

NOTE: Nuxt doesn't know you want to use Vuex until you tell it. The way you tell it is by creating a file in the store directory. This may not take affect immediately, so after creating a file, restart your dev server to be safe.

In /store create a file called drawer.js and provide the following contents to get started.

export  const  state  = () => ({
  drawer:  false
});
Enter fullscreen mode Exit fullscreen mode

This gives us an initial value to start off with, but we'll want to be able to toggle this obviously, so in that same file we'll create a mutation as well called toggle.

export  const  mutations  = {
  toggle(state) {
    state.drawer  =  !state.drawer;
  }
};
Enter fullscreen mode Exit fullscreen mode

Lastly, we need to be able to get the value at any time which we'll do with a getter.

export  const  getters  = {
  getDrawerState(state) {
    return  state.drawer;
  }
};
Enter fullscreen mode Exit fullscreen mode

Once you have all of these in your drawer.js module, you'll effectively be able to use your navigation drawer from any component!

Using your mutation & getter to toggle the sidebar

You'll have 1 component where you'll need your getter, in the SideBar component to bind to the v-if directive so your Vue app knows when the SideBar should be rendered.

You'll have 2 components where you'll need your mutation, in the NavBar component for opening the SideBar, and in the SideBar to close the SideBar.

First lets make sure your SideBar knows when its allowed to come out. In your SideBar component just after your <script> opening tag, import mapGetters & mapMutations from vuex.

import { mapGetters, mapMutations } from 'vuex';
Enter fullscreen mode Exit fullscreen mode

Next we'll want to map our getter as a computed property called drawer which when evaluated as true, shows our sidebar. As well, we can map our toggle mutation to a method to bind to our close button.

export  default {
  methods: {
    ...mapMutations({ toggle:  "drawer/toggle" })
  },
  computed: {
    ...mapGetters({ drawer:  "drawer/getDrawerState" })
  }
};
Enter fullscreen mode Exit fullscreen mode

Same as above in our NavBar we'll map our toggle mutation to use in our hamburger button so we can open the SideBar and you're all set!

Conclusion

That's pretty much it. We've seen a bit about how Nuxt structures our Vue application, how namespaced modules work with Nuxt & Vuex, and how we can use mapGetters & mapMutations to handle basic functionality like toggling a sidebar from any component!

Top comments (4)

Collapse
 
kp profile image
KP

Nice! Definitely a big fan of Vue and Nuxt and would love to see more packages and plugins using these.

Collapse
 
fkoeppling profile image
Fabian Köppling

The SideBar template is the same as the NavBar template.

Collapse
 
mjlehrke profile image
Michael J. Lehrke

@codespent the example code for the SideBar template is just a repeat of the NavBar code.

Collapse
 
_phumbie profile image
Mr. Dawodu

I don't know why this didn't work for me, copied everything and made changes where necessary