What is the best way to use v-bind to toggle a class on a specific element in VueJs?

My app features a bottom navigation bar with 4 icons that, when clicked, change the displayed view. I want the selected icon to switch from white to red. To achieve this, I thought of toggling the class of .active when an icon is selected. However, my current code toggles the class of all list items instead of just the selected one. Additionally, I need the first list item to be set as active by default. Is there a way to accomplish this?

The structure of my navigation component is as follows;

<li v-on:click="active = !active" v-bind:class="{active: active}">
    <router-link to="/pageOne">
        <i>Icon 1</i>
    </router-link>
</li>
<li v-on:click="active = !active" v-bind:class="{active: active}">
    <router-link to="/pageTwo">
        <i>Icon 2</i>
    </router-link>
</li>
<li v-on:click="active = !active" v-bind:class="{active: active}">
    <router-link to="/pageThree">
        <i>Icon 3</i>
    </router-link>
</li>
<li v-on:click="active = !active" v-bind:class="{active: active}">
    <router-link to="/pageFour">
        <i>Icon 4</i>
    </router-link>
</li>

Below this structure, is the accompanying script;

<script>
export default {
  name: "PrimaryAppNav",
  data() {
    return {
      active: false
    };
  }
};
</script>

Answer №1

If you want an alternative solution instead of using a click event handler to manage the toggling of the active class, here's another approach:

You can create a method within your PrimaryAppNav component that checks the current active route path and returns a boolean value.

By following this method, you won't need to keep track of the currently active route in your component state like you're currently doing with the active property.

<li v-bind:class="{ active: isActivePath('/pageOne') }">
    <router-link to="/pageOne">
        <i>Icon 1</i>
    </router-link>
</li>
<li v-bind:class="{ active: isActivePath('/pageTwo') }">
    <router-link to="/pageTwo">
        <i>Icon 2</i>
    </router-link>
</li>
<li v-bind:class="{ active: isActivePath('/pageThree') }">
    <router-link to="/pageThree">
        <i>Icon 3</i>
    </router-link>
</li>
<li v-bind:class="{ active: isActivePath('/pageFour') }">
    <router-link to="/pageFour">
        <i>Icon 4</i>
    </router-link>
</li>

Within your PrimaryAppNav component, add the following method to the methods property:

isActivePath(path) {
  return this.$route.path === path;
}

Answer №2

Perhaps it could be structured like this:

<template>
<li @click="toggleActive('pageOne')" :class="{active: active === 'pageOne'}">
    <router-link to="/pageOne">
        <i>Icon 1</i>
    </router-link>
</li>
<li @click="toggleActive('pageTwo')" :class="{active: active === 'pageTwo'}">
    <router-link to="/pageOne">
        <i>Icon 2</i>
    </router-link>
</li>
</template>

<script>
export default {
  data() {
    return {
      active: 'pageOne'
    }
  },
  methods: {
    toggleActive(page) {
      this.active = page
    }
  }
}
</script>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Unable to create a clickable button within a CSS3DObject using Three.js

How can I create an interactive button on a CSS3DObject within a cube made up of 6 sides? The button is located on the yellow side, but I'm facing issues with clicking on it. Whenever I attempt to click on the button, the event.target always points to ...

With Vue's new implementation of adding data attributes to the "*" selector, how can I adapt to this change?

Typically, I reset all margins/paddings by including the following code snippet at the beginning of my CSS: *, body { margin: 0; padding: 0; } This method usually works fine since it is overridden by subsequent selectors. However, Vue appends data att ...

Is there a way to determine if a line has been automatically wrapped within a textarea element?

Is it possible to detect when text is wrapped onto the next line in a textarea after becoming wider than the area? ...

What is the best way to showcase navigation and footer on every page using AngularJS?

I'm in the process of building a Single Page Application. I've decided to create separate components for Navigation, Section, and Footer. The Navigation and Footer should be displayed on every page, while only the Section content changes when nav ...

What is the best way to set up Storybook with Vue Cli 3?

I'm facing difficulties installing Storybook in a Vue Cli 3 project. Every time I try to npm run storybook, I encounter this error: Cannot find module '@storybook/vue/dist/server/config/defaults/webpack.config.js' I suspect that this i ...

Filtering function that works without specific knowledge of keys

I'm working on a JavaScript method to filter a list dynamically without knowing the specific key (s). I've made some progress, but I'm stuck and not sure how to proceed. The foreach loop I have isn't correct, but I used it for clarity. ...

Automated Facebook Wall Publishing

I have successfully integrated a feature in my application where users can post status updates, photos, and URLs on their Facebook Like stream. I have also added an option for users to post directly on Facebook by including a checkbox. When the user clicks ...

What is the best way to restore the original form of a string after using string.replaceAll in javascript

To ensure accurate spelling check in JavaScript, I need to implement text normalization to remove extra whitespaces before checking for typos. However, it is crucial to keep the original text intact and adjust typo indexes accordingly after normalization. ...

Utilizing the colon (:) in Vue Router: A Guide

My URL is not updating correctly after the push. I am trying to format it as: www.abc.com/istanbul-taksim-otelleri?checkin=2019-05-08&checkout=2019-05-16&filters=meal_types:full,half,etc;stars:1,2,4 const query = { checkin: '2019-05-08& ...

Debugging Windows Node.js applications remotely on Azure Web Apps or Azure Functions

I'm working with Windows-based Node.js applications deployed on Azure Web Apps or Azure Functions. It looks like the Visual Studio Code (VSC) extensions are intended for Linux environments only. What is the best way for me to debug these application ...

Implementing Multiselect Filter Functionality in Vue.js

Can someone help me with adding my selected locations and types to the filteredHotels() method in order to filter the results based on user selections? For instance, I need to filter Sydney Hotels, Sydney Backpackers, Sydney or Melbourne hotels, or all hot ...

Developing bi-directional binding for newly generated elements post initial compilation

I have developed a directive that dynamically generates a form based on a JSON received from the server. I am trying to include the ng-model attribute in the input elements so that I can access the input values once the user enters them and clicks submit. ...

In mongoose.js, the Model.updateOne() function takes precedence over the Document.save() method when executing

I have been experimenting with MongoDB using mongoose.js to grasp its functionality. My goal is to insert a document and update it. However, upon running app.js, the console logs "Successfully updated," yet when I check the mongo shell, the review: "Pret ...

Finding All Initial Table Cells in jQuery

Is there a streamlined method for retrieving all td elements (cells) from every row within a specific table, or do I have to manually iterate through the collection myself? ...

Whenever I try to access a specific position within a JSON array, I receive the value of 'undefined'

After executing a database query in PHP and returning the results through AJAX in a JSON array, I am facing an issue where the data is being accessed as 'undefined'. Why is this happening? Below is my PHP code snippet: <?php $tipo_prod ...

What is the method for conducting an Ajax request?

Currently, I am deeply involved in a personal project to enhance my skills with Rails. The project involves developing a task management application that encompasses three primary states: todo, in progress, and done. After numerous days of trial and error, ...

Comprehend the angular and in a confined scope and its brackets

I have been wondering why I have to use double brackets ()() when passing a method from an outer scope to a directive with an isolated scope using '&'. It seems like the function is returned with callThat() and then I need to call it with anothe ...

What is the reason behind mounting Bootstrap-Vue tables as "b-table-stub" instead of just "b-table" in unit testing with @vue/test-utils?

I'm new to unit testing in Vue and I am using @vue/test-utils for the first time. Here is the code snippet from my Foo.vue file: <template> <div class="hello"> <b-table striped hover :items="items"></b-ta ...

Testing AngularJS directives with external templates for unit testing

I have been utilizing the npm package karma-ng-html2js-preprocessor to achieve this task. This is the content of my spec file: describe('Directive: aGreatEye (external)', function() { var elm, scope; beforeEach(module('my-thing.te ...

What is the best way to navigate around and close this modal?

Hey everyone, I've been experimenting with the JavaScript on this codepen and I'm trying to make it so that when you click the background, the modal closes. However, I've run into two issues: The .modal is contained within .modal-backgroun ...