1

I want that, clicking on a menu item, the active class is triggered only for that specific item and removed for the others, until now I wrote this:

<template>
  <nav class="navbar">
    <div class="navbar__brand">
      <router-link to="/">Stock Trader</router-link>
    </div>
    <div class="navbar__menu">
      <ul class="navbar__menu--list">
        <li @click="isActive=!isActive" class="navbar__menu--item" :class="{active:isActive}">
          <router-link to="/portfolio">Portfolio</router-link>
        </li>
        <li @click="isActive=!isActive" class="navbar__menu--item" :class="{active:isActive}">
          <router-link to="/stocks">Stocks</router-link>
        </li>
      </ul>
    </div>
    <div class="navbar__menu--second">
      <ul class="navbar__menu--list">
        <li @click="isActive=!isActive" class="navbar__menu--item" :class="{active:isActive}">
          <a href="#">End Day</a>
        </li>
        <li @click="isActive=!isActive" class="navbar__menu--item" :class="{active:isActive}">
          <a href="#">Save / Load</a>
        </li>
      </ul>
    </div>
  </nav>
</template>
<script>

    export default {
      data(){
        return{
          isActive: false

        }
      }
    }
</script>

now of course, when I click on one item the active class is inserted/removed for all the items, what is the best solution for making that only a specific item, on clicking on it, receives the active class?

5 Answers 5

6

You'll want some sort of identifier for each clickable item and set that to your data property. For example

data() {
  return { active: null }
}

and in your list items (for example)

<li @click="active = 'portfolio'"
    class="navbar__menu--item" 
    :class="{active:active === 'portfolio'}">

In this example, the identifier is "portfolio" but this could be anything, as long as you use a unique value per item.

Sign up to request clarification or add additional context in comments.

Comments

3

You could keep an object of links you have and handle a click on each of items. E.g.

data() {
  return {
    links: [
      {
        title    : 'Portfolio',
        to       : '/portfolio',
        isActive : false,
        location : 'first',
      },
      {
        title    : 'Stocks',
        to       : '/stocks',
        isActive : false,
        location : 'first',
      },
      {
        title    : 'End Day',
        to       : '#',
        isActive : false,
        location : 'second',
      },
      {
        title    : 'Save / Load',
        to       : '#',
        isActive : false,
        location : 'second',
      },
    ]
  };
},
methods: {
  handleNavClick(item) {
    this.links.forEach(el, () => {
      el.isActive = false;
    });

    item.isActive = true;
  }
},

2 Comments

This is the better way to do navs
Also, this approach can help you to decrease the size of your template using circles for links output.
0

I do this in vue3. the template is:

<li
  v-for="(title, index) in titles"
  class="title"
  :key="index"
  :class="{ active: active === index }"
  @click="updateActive(index)"
>
   {{ title }}
</li>

and the script is

<script lang="ts" setup>
import { ref } from "vue"
const titles = ["title1","title2","title3"]
const active = ref(-1)

function updateActive(val: number) {
  active.value = val
}
</script>

Comments

0

If you have several ul => use title instead of index. For example :

<ul>
                <div>
                    Applicants
                </div>
                <li
                    v-for="(title, index) in applicantMenuTitles"
                    :key="index"
                    :class="{ active: active === title }"
                    @click="updateActive(title)"
                >
                    {{ title }}
                    <div
                        v-if=" active === title "
                        class="cursor"
                    />
                </li>
            </ul>
            <ul>
                <div>
                    Offices
                </div>
                <li
                    v-for="(title, index) in officeMenuTitles"
                    :key="index"
                    :class="{ active: active === title }"
                    @click="updateActive(title)"
                >
                    {{ title }}
                    <div
                        v-if=" active === title "
                        class="cursor"
                    />
                </li>
            </ul>
And on script :

...
const active = ref('')

function updateActive(title: string) {
    active.value = title
}

Comments

0

Here is custom menu active no dynamic menus. This working like Laravel

       <li class="sidebar-dropdown" :class="$route.name === 'CategoryEdit' || $route.name === 'CategoryCreate' || $route.name === 'Categories' ? 'active' : ''">
          <a><i class="fa fa-cubes"></i> <span>Categories</span></a>
          <div class="sidebar-submenu" :class="$route.name === 'CategoryEdit' || $route.name === 'CategoryCreate' || $route.name === 'Categories' ? 'd-block' : ''">
            <ul>
              <li :class="$route.name === 'Categories' ? 'subactive' : ''">
                <router-link :to="{name: 'Categories'}">List</router-link>
              </li>
              <li :class="$route.name === 'CategoryCreate' ? 'subactive' : ''">
                <router-link :to="{name: 'CategoryCreate'}">Create</router-link>
              </li>
            </ul>
          </div>
        </li>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.