Creating a dynamic (Active tabs) menu in Vuejs ✨
Tags: vue, webdev, beginners, learning
Published: 2020-02-04 07:31:24

<h4>Hello, users! 👋</h4>

Today I wanted to teach you how to transform **this** kind of menu 👇

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/sax0b4icjm8rihlj93b0.gif)

To **this** 👇 other kind of dynamic menu, where you can see **active** tabs when you select them:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/6kt8lovtc34imtbvk8ce.gif)

in whatever style that suits you:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/13io5uqcy6wre6b7ghmr.gif)

I'll be using **Vue cli 3** and **SASS**. But don't worry, code is actually easy to understand even if you don't know SASS.

You'll be able to check also a **repo** in Github with the source code of this article and you can also check the process below this words

<h2>First of all, why should I build a dynamic menu with active tabs?</h2>

The answer to 50% of questions in the web-design/development field is: **usability**, and the other half, **accessibility**.

Using an **active tabs** design for your menu will increase your usability by letting the user know

👉 where she/he is
👉 what she/he just clicked
👉 where she/he **is not** (this may be too obvious but there are some times when our brain detects colors before letters and if we know that the "contact" option is at the end but we see the active tab at the beggining we already know **where we aren't**)
👉 because we can

<h2>Setting up</h2>

You'll need Vue Cli installed. If you don't have it, **create a folder in your desktop**, open your *cmd* inside that folder and type

```cmd
npm install -g @vue/cli
```

Perfect. Now it's time to create a new Vue project by using
```cmd
vue create nameyourprojecthere
```

set your project manually and don't forget to use the options
👉 router (without history mode)
👉 SASS preprocessor (the one you like)

and that's it.

In case **you already have a Vue project where you'd like to create a dynamic menu** but **you don't have SASS** please see <a href="https://dev.to/helleworld_/integrating-dart-node-sass-in-vuejs-4o39">this</a>.

<h2>The project structure</h2>

For the purpose of this article I'll be having **4 views**: Home, Articles, Gallery and Contact.

Therefore, I have 4 **.vue** files in my **views** folder, like this:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/yhxed2jqltykg8zxktim.gif)

and the code inside each of those views is as follows

```html
<template>
  <div>
    <h1>This is a (type) page</h1>
  </div>
</template>
```
and inside our **router** folder, in our index.js file inside of it, the code is also as follows:

```javascript

[...]

//all my routes are directed to the views:

const routes = [
  {
    path: '/',
    name: 'home',
    component: Home
  },
  {
    path: '/articles',
    name: 'articles',
    component: function () {
      return import('../views/Articles.vue')
    }
  },
  {
    path: '/gallery',
    name: 'gallery',
    component: function () {
      return import('../views/Gallery.vue')
    }
  },
  {
    path: '/contact',
    name: 'contact',
    component: function () {
      return import('../views/Contact.vue')
    }
  }
]

[...]

```

But this is just so we can add some **real functionality** to our project. We'll focus in our **App.vue** file. Inside this file, **the magic will begin**.

<h2>Creating the monster</h2>

**Please note your code could be different if you just created your project with Vue Cli. I'm not changing that code, I'm explaining how and why it works, so please read carefully** :)

First of all, what we have here? 

The **App.vue** file is a big, huge, boss-ninja-rockstar in our project. Why? Because inside this file we'll have our **< router-view/ >** element, which decides what we're seeing in our screen **depending on the url** we're visiting.

We have the following **template**:

```html
<template>
<!-- Our #app div contains our website -->
  <div id="app">
    <!-- Our #nav div contains our beloved menu -->
    <div id="nav">
      <!-- with router-link we manage the url's of our website -->
      <router-link to="/">Home</router-link>
      <router-link to="/articles">Articles</router-link>
      <router-link to="/gallery">Gallery</router-link>
      <router-link to="/contact">Contact</router-link>
    </div>
    <router-view/>
  </div>
</template>
```

and the following **styles** (in SASS):

```
<style lang="scss">
//Okay I'm just importing a font here from GoogleFonts that I like A LOT 
@import url('https://fonts.googleapis.com/css?family=Poppins&display=swap');
$font: 'Poppins', sans-serif;

//This is our #app div, it contains the whole universe of our website
#app{
  text-align: center;
}

//This is our #nav div, it contains our menu
#nav {
  padding: 30px;

  //We're using SASS, so we're nesting the links inside the #nav div here
  a {
    color: inherit;
    margin: 0.667em;
    font-family: $font;
    text-decoration: none;
  }
}
</style>
```

Right now, this is what we have

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/0xkvdyriab2zpnt2n00m.gif)

First of all, let's include an indicator to our menu to make it look more "tab-like". Choose one! It can be from the emoji 👇, to 🤘, 👌 or a simple symbol like ⤸, ˅ or ⋮.

Choose your own indicator visiting the <a href="https://getemoji.com/">emoji page</a> and the <a href="https://coolsymbol.com/">symbols page</a>.

We'll include the indicator with a **span** tag inside our **router-link** tag, like this:

```html
    <div id="nav">
      <router-link to="/">Home <span>👇</span></router-link>
      <router-link to="/articles">Articles <span>👇</span></router-link>
      <router-link to="/gallery">Gallery <span>👇</span></router-link>
      <router-link to="/contact">Contact <span>👇</span></router-link>
    </div>
```

It'll look like this:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/oah5qfo1b38fwrgmjlw6.PNG)

Now... We **don't** want our indicators to show all the time, right? Just when the section they belong to is clicked.

We'll add one state to our **SASS**, called: *&.router-link-exact-active*. You could read more about this <a href="https://router.vuejs.org/api/">here</a>, the essence of this state is that the styles we're using inside it will only be active when the URL of the link it's **active** (*active* here, meaning that the user actually is visiting that URL by clicking on it).

First, we'll tell our SASS that the **span** inside our links by default will have **display:none**, we don't want to see it all the time:

```

#nav {
  padding: 30px;
  
  a {
    color: inherit;
    margin: 0.667em;
    font-family: $font;
    text-decoration: none;
    //Bye bye by default, sweetheart
    span {
      display: none;
    }
  }
}
```

and now, right below that, we'll tell our SASS that the span actually **will** be displayed when the state *&.router-link-exact-active* is actually active:

```
#nav {
     [...]
  a {
     [...]

    &.router-link-exact-active {
      //And, hello again!
      span {
        display: inline-block;
      }
    }
  }
}
```

Now we'll have this:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/xj8ssw581zmk8etynsrj.gif)

**Easy**, right?

Believe it or not, we're already **done** here.

<h2>Time for your imagination</h2>

Now it's time for you to use your **imagination and creativity**, and use as many styles as you'd like to in your SASS.

**Remember** that the styles for the **Active** tab **must** be placed inside the 

```
&.router-link-exact-active {
    //inside here
    }
```

*&.router-link-exact-active* state. Use borders, background-colors, shadows... As you'd like to!

However, I'll give you some ideas with these designs:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/xmzf9prarjbejyqkayol.png)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/obfp4b6p7adui4xt7bmo.png)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/d63r1k6cyflkcfwx5c0h.png)

<h2>In conclusion</h2>

Thank you for reading this far!

You can get the **source code** for this menu <a href="https://github.com/helleworldGIT/Vue-Dynamic-TabLike-Menu">here</a>, or also visiting <a href="https://desiremcarmona.com/#/">my website</a> where I created a cute menu.

In case you create your own style active-tab menu, share it with us in the comments!

See you around, let's keep coding and learning 💻!