Implement a function within a v-for iteration

Currently, I am facing a challenge in Vue 3 while attempting to design a menu with categories and corresponding subcategories. The objective is that upon clicking on a category, only the specific subcategories related to that category should be displayed below, and they should disappear upon another click. However, my issue lies in achieving this functionality for each individual category. Every time I click on a category, all subcategories from every category are being shown.

To provide more context, I have simplified my code into an example:

JS :

const menu = [
  {
    label: "Category 1",
    key: "category_1",
    subcategories: [
      {
        label: "1 - Subcategory 1",
        key: "1_subcategory_1",
      },
      {
        label: "1 - Subcategory 2",
        key: "1_subcategory_2",
      },
    ],
  },
  {
    label: "Category 2",
    key: "category_2",
    children: [
      {
        label: "2 - Subcategory 1",
        key: "2_subcategory_1",
      },
    ],
  },
];

const isDisplay = ref(false);

const showSubcategories = () => {
  isDisplay.value = !isDisplay.value
}

VUE :

<template>
  <div v-for="category in menu" :key="category.key">
    <div @click="showSubcategories()">
      <span> {{ category.label }}</span>
    </div>
    <div v-if="isDisplay">
      <div
        v-for="subcategory in category.subcategories"
        :key="subcategory.key"
      >
        {{ subcategory.label }}
      </div>
    </div>
  </div>
</template>

I have tried adding an index or passing parameters such as showSubcategories(category.key) to my function, but so far, I have not been able to resolve the issue. Any help or suggestions would be greatly appreciated. Thank you.

Answer №1

If you're looking to implement this functionality, there are a couple of ways you can approach it. One option is to add an additional property to each category to keep track of whether it is open or closed. Another approach would be to use a separate variable to store the IDs of categories that are currently open.

Here's an example using a separate variable to store open category IDs:

const menu = [
  {
    label: "Category 1",
    key: "category_1",
    subcategories: [
      {
        label: "1 - Subcategory 1",
        key: "1_subcategory_1",
      },
      {
        label: "1 - Subcategory 2",
        key: "1_subcategory_2",
      },
    ],
  },
  {
    label: "Category 2",
    key: "category_2",
    subcategories: [
      {
        label: "2 - Subcategory 1",
        key: "2_subcategory_1",
      },
    ],
  },
];

const openCategories = ref([]);

const toggleSubcategories = (categoryId) => {
  if(openCategories.value.includes(categoryId)) {            
    openCategories.value.splice(openCategories.value.indexOf(categoryId), 1);
  } else {
    openCategories.value.push(categoryId);
  }
}
<template>
  <div v-for="category in menu" :key="category.key">
    <div @click="toggleSubcategories(category.key)">
      <span> {{ category.label }}</span>
    </div>
    <div v-if="openCategories.includes(category.key)">
      <div
        v-for="subcategory in category.subcategories"
        :key="subcategory.key"
      >
        {{ subcategory.label }}
      </div>
    </div>
  </div>
</template>

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

Using JavaScript, enter the value into the input field and then redirect the

I'm encountering a minor issue with my contact form and jQuery redirection based on input fields. Everything was working smoothly until I attempted to integrate the redirection into the form validation code. Redirection snippet: $("#signup").submit ...

Enabling client-side access to collections without the need for meteor startup

Whenever I define my Meteor collections on the server and attempt to access them in the client without being within any of the predefined Meteor methods such as rendered, events, created, or helpers, I consistently encounter an error stating Meteor colle ...

Obtain the identification address for a group of items

I have a JSON object containing place IDs, and I am attempting to retrieve the corresponding addresses for each ID. This is the code snippet I'm using: <div id="places" class="places"></div> <script> function initialize() { j ...

Can you point me to the source of definition for Vue 2's ComponentDefinition and ComponentConstructor types?

I am struggling to add a dynamic Vue 2 component with correct typing in TypeScript. The documentation clearly mentions that the is attribute accepts values of type string | ComponentDefinition | ComponentConstructor, but I cannot locate these custom types ...

Error: The AjaxMethod "Class" is not defined

I have an older asp.net project that utilizes Ajax.AjaxMethod() to invoke server-side code from Javascript. It used to function properly, but now it has suddenly ceased to work. Here is the C# code behind: public partial class Signup : System.Web.UI.Page ...

What is the best way to style MUI's Button component with a link to appear like a standard button?

I have a Button that allows users to download a file with a specific filename. Here is the code I used: <Button color='primary' href=`/apiproxy/objects/${id}/subobjects` LinkComponent={React.forwardRef((props, ref) => <Link {...pro ...

Dealing with images in Laravel Mix

Recently, I made the switch from Vue-CLI to laravel-mix and encountered an issue with my images in HTML not displaying. Previously, I was using the following syntax: <img src="@assets/images/logo.png" alt="Logo"> (Where @assets a ...

In my upcoming app, I incorporated a tradingview widget that occasionally experiences a glitch. Specifically, when navigating away from and back to the widget, the chart disappears. However, a simple refresh corrects the

Below is the code snippet for embedding a tradingview chart. The script loads the imported tradingview function on page load, and I've included a function to reload the dashboard programmatically onClick event. import Script from "next/script&quo ...

Vue code is successfully loading environment variables, however, they are not functioning as expected

I encountered a peculiar issue. When trying to verify a JWT inside a Vue component, I found that using the secret key hardcoded as shown below works fine and successfully verifies the JWT signature. However, when attempting to use the secret key stored in ...

AngularJS is experiencing delays when processing subsequent $http delete requests, leaving them stuck in a

I am currently working on a project where I have a table displaying a list of objects, with each object having multiple child objects associated with it. The technologies I am using include Angular 1.2.20, Express 4.6.1, and Node 0.10.25. In the table, the ...

Steps for embedding a function within another function

One method I know is by using this hack: function executeFunction(func){ setInterval(func,0); } executeFunction("newFunction()"); However, I am searching for a more elegant solution. ...

What is the process for logging in or authenticating before running tests with pa11y-ci?

Is there a way to authenticate users and test pages using pa11y-ci? When running pa11y-ci, I typically use this command: pa11y-ci --sitemap http://www.example.com/sitemap.xml --sitemap-find https --sitemap-replace http I came across some helpful informa ...

Refreshing the page allows Socket.io to establish multiple connections

I've been working on setting up a chatroom, but I've noticed that each time the page refreshes, more connections are being established. It's interesting because initially only one connection is created when I visit the chat room page. Howeve ...

The tooltip feature is malfunctioning

The content: <table class="table table-hover"> <?php foreach ($query as $row){ echo '<tr ><td > <label class="checkbox"> '.form_checkbox('delete[]', $row['link']).anchor("site ...

Increased impact of dynamically added elements following page transition

After implementing dynamic functionality from jQuery in my code, I encountered an issue where if I navigate back one page and then return to the original page containing the added elements, they seem to trigger twice upon clicking. To troubleshoot, I incl ...

Can you explain how to incorporate a node module script into a React.js project?

I have encountered an issue where the element works perfectly fine when using an external node module, but fails to function properly when using a locally downloaded node module. Unfortunately, I am unable to identify the root cause of this problem. You c ...

Combining the Partial<CssStyleDeclaration> union type with a dictionary can lead to potential typing complications when the implicit any flag is

Using VueJS v-bind:style binding makes it possible to set CSS variables. I am attempting to create a union type that allows for the object passed to v-bind:style to retain typings for CssStyleDeclaration, while also being relaxed enough to accept an arbitr ...

Issue with AngularJS binding not updating when the initial value is null and then changed

I am encountering an issue with my binding not updating, and I have a hypothesis on why it's occurring, but I'm unsure about how to resolve it. Within my controller, there is a company object that includes a property called user, which may or ma ...

Converting between GPS degrees and decimal values using jquery, javascript, and PHP: A comprehensive guide

Is there a way to convert GPS degree to decimal values or vice versa? I am working on developing a feature where users can input an address and retrieve the GPS values in both degree and/or decimal format. However, my main challenge is understanding how t ...

When a change is made in the parent component, the local state of the child component in ReactJS is automatically updated

I'm currently facing a challenge while implementing a custom dropdown filter for a table in react. Each column has a set of dropdown values with an Apply button. To handle this, I've created a child component that takes the dropdown values and s ...