Vue 3: Displaying a Tree Menu

Just to clarify my intentions... Whenever Menu 1 is clicked, its corresponding ul should be displayed. Similarly, when Menu 2 is clicked, its associated ul should be shown. This behavior extends to hiding the ul if the same menu item is clicked again.

Could someone provide an example illustrating how I can achieve this?

Menu 1 Click = Toggle ul display

<ul>
    <li v-for="(item,index) in menuData" :key="index">
      <router-link :to="item.path" exact @click.stop="showMenu(index)">{{ item.name }}</router-link>
      <ul v-if="item.children" v-show="selected === index">
        <li v-for="(childItem,ChildIndex) in item.children" :key="ChildIndex">
          <router-link :to="childItem.path">{{ childItem.name }}</router-link>
        </li>
      </ul>
    </li>
  </ul>
<script>
export default {
  name: "App",
  data() {
    return {
      openshow: false,
      selected: null,
      menuData: [{name: "Home", path: "/",}, {name: "About", path: "/about",}, {name: "Menu 1", path: "#", children: [{name: "Menu 1.1", path: "/menu/1/1",}, {name: "Menu 1.2", path: "/menu/1/2",}, {name: "Menu 1.3", path: "/menu/1/3",},],}, {name: "Menu 2", path: "#", children: [{name: "Menu 2.1", path: "/menu/2/1",}, {name: "Menu 2.2", path: "/menu/2/2",}, {name: "Menu 2.3", path: "/menu/2/3",},],}, {name: "Gallery", path: "/gallery",}, {name: "Contact", path: "/contact",},],
    }
  },
  methods: {
    showMenu(index) {
      this.selected = (this.selected === index) ? null : index;
    }
  }
}
</script>

Answer №1

To display the desired menu, simply utilize the showMenu method with the designated index and then determine which ul to showcase by passing the index to the showCollapsed method:

const app = Vue.createApp({
   data() {
    return {
      openshow: false,
      selected: null,
      menuData: [{name: "Home", path: "/",}, {name: "About", path: "/about",}, {name: "Menu 1", path: "#", children: [{name: "Menu 1.1", path: "/menu/1/1",}, {name: "Menu 1.2", path: "/menu/1/2",}, {name: "Menu 1.3", path: "/menu/1/3",},],}, {name: "Menu 2", path: "#", children: [{name: "Menu 2.1", path: "/menu/2/1",}, {name: "Menu 2.2", path: "/menu/2/2",}, {name: "Menu 2.3", path: "/menu/2/3",},],}, {name: "Gallery", path: "/gallery",}, {name: "Contact", path: "/contact",},],
    }
  },
  methods: {
    showMenu(index) {
      this.selected === index ? this.selected = null : this.selected = index;
    },
    showCollapsed(idx) {
      return idx === this.selected || false
    }
  }
})
app.mount('#demo')
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<div id="demo">
  <ul>
    <li v-for="(item,index) in menuData" :key="index" @click="showMenu(index)">
      <router-link :to="item.path" exact>{{ item.name }}</router-link>
      <ul v-if="item.children" v-show="showCollapsed(index)">
        <li v-for="(childItem,ChildIndex) in item.children" :key="ChildIndex">
          <router-link :to="childItem.path">{{ childItem.name }}</router-link>
        </li>
      </ul>
    </li>
  </ul>
</div>

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

AngularJS provides a convenient way to manage content strings

As I embark on developing a large AngularJS application, I am faced with the need to manage UI text content. This is crucial as elements like contextual help will require post-launch editing by the client in response to user feedback. I am currently explo ...

Tips for correctly deleting a duplicate ref Object ID following the removal of a Document

Coming from a background in relational databases, I'm encountering a challenge with a pattern in Mongoose. Let's say we have SchemaA and SchemaB (for example, pets and people): const Person = new Schema({ name: String, pets: [{ ref: ...

Looking to create several Vuex modules to correspond with various Vue instances

Currently, I am in the process of integrating Vue into a website for form functionality. This involves creating multiple instances of the Vue application if there are multiple forms on the page. The key point to note is that all instances will be utilizing ...

Error: Bootstrap fails to load fonts when used with webpack

Struggling to configure webpack 4 for my project. File structure required for bootstrap integration: public css images js vendor bootstrap\dist css fonts glyphicons-halflings-regular.eo ...

There was a problem compiling the template and an error occurred in the mounted hook

I am encountering a slight issue with testing Vuejs and I am unsure how to resolve the error. Error1: "[Vue warn]: Error compiling template: Component template should contain only one root element. If you are using v-if on multiple elements, use v-e ...

What could be causing me to lose my login information on my React application?

I have a reactjs application that utilizes a django backend for handling authentication. Below is a snippet of my Typescript code from the App.tsx file in my react app: import React, {useState, useEffect} from 'react'; import { BrowserRouter as ...

Issue: You cannot render Objects in React components. Consider using an array if you intended to render a collection of children

I've encountered an error message that has me stumped. My goal is to upload an image into the database and have it displayed on screen. However, every time I attempt to upload an image, instead of rendering it on the screen, I receive this error mess ...

What sets apart the npm packages @types/express and express?

Can't decide whether to use @types/express or express for building a node server? Take a look at the code snippet below: 'use strict'; const express = require('express'); const http = require('http'); const path = requir ...

Retain the user's input in the text box even after the form has been submitted

Currently, I am tackling the challenge of creating a register form with an error handler to manage any mistakes made by users during registration. Once the form is submitted, potential errors are displayed to the user. To enhance user experience, I am ex ...

Verify that the zip code provided in the input matches a record in the JSON data and extract the

I need to create a feature where users can input their zip code, check if it matches any of the zones in a JSON element, and then display the corresponding zone: var zones = [{ "zone": "one", "zipcodes": ["69122", "69125", "69128", "69129"] }, ...

What is the best way to regain grid focus following a data reload in ExtJS?

Within my ExtJS view, there is a grid where users can select an entry along with a panel displaying details about the selected row. However, every time a different row is chosen, the view is reloaded causing the grid to lose focus for keyboard navigation. ...

Remove items from an array in a random order until it is completely emptied

My goal is to choose a random element from an Array and then remove it, repeating this process until the Array is empty. I have experimented with the .filter() function and Math.random without success. I also attempted to implement it within a for loop, b ...

Utilizing JSON and AJAX for data parsing

I have a PHP page that contains the following code: <?php $library= '{"closets":[ {"id":"001","theme":"literature","shelves": { ...

Tips for ensuring a scrollbar remains at the bottom position

I'm facing an issue with a scroll-bar inside a div element. Initially, the position of the scroll-bar is at the top. However, whenever I add text to the div element, the scroll-bar remains in its initial position and does not automatically move to the ...

stop the leakage of CSS and JS from the subtree to the document through the inverse shadow DOM mechanism

My page contains dynamic HTML content that I want to incorporate. The dynamic content consists of only HTML and CSS, without any JavaScript. However, I have some custom global CSS styles and JS logic that need to be implemented along with this dynamic con ...

``What is the best way to set up the Vue app based on the initial back-end response?

I'm in need of a way to run some code before any other functionality in my app is executed. This code needs to send a request to the back-end and update the store first, as route guards depend on it. How can I achieve this? Code Example Fetching user ...

Display a div based on search results

I recently encountered an issue with a script that needs modification to display different divs based on search criteria. Originally, I used this script for a contact list but now need it to perform another function. View the original code (JSFiddle) Here ...

use the useState hook to update an array of objects by adding a new object

Currently, I am in the process of developing a straightforward order list web application using react hooks. Within this app, there is an orders state that gets updated whenever a user clicks on a product image in the shopping panel. When this action occur ...

Decode the JSON serialized format generated by CircularJSON

I have a JSON object in my node.js code that contains circular references. To send this information to the browser, I utilized the NPM package circular-json to stringify the object and serialize the circular references: var CircularJSON = require("circula ...

No data is being returned by the Jquery Ajax function

I am experiencing an issue with a Jquery Ajax call in my code: $('body').on('click', '#btnPopulate', function() { alert(getTree()); }); function getTree() { var url = getUrlPath() + "/StoryboardAdmin/BuildStoryboardViewMode ...