Creating a dropdown feature for menu items in Vue when the number or width of items exceeds the menu bar's limits

I am working on a navigation bar that displays menu items as tabs. One issue I am encountering is when the number of menu items exceeds the space available, I need to move the excess items into a dropdown menu (showmore) using Vue.

Here is an example of the output image: output image


      <template>
        <div class="nav">
          <nav class="navigation">
            <ul>
              <li v-for="(item, index) in groups" :key="`nav-${index}`" >
                <router-link class="router-link-tab" :to="item.name.toLowerCase()">{{item.name}}</router-link>
              </li>
           </ul>
          </nav>
         </div>
       </template>

<script>
  export default {
    name: 'Tab',

    props: {
      back: {
        type: Boolean,
        default: true,
      },
    },
  }
</script>

Answer №1

Finding a simple solution may be challenging, but I have crafted an example specifically for you. To customize it to your liking, all you need to do is adjust the CSS. This approach demonstrates one method of achieving the desired outcome.

Check out the example here

<template>
  <div id="app">
    <nav class="navigation" ref="nav">
      <div
        style="display: inline"
        v-for="(item, index) in groups"
        :key="`nav-${index}`"
        :ref="`nav-${index}`"
      >
        <router-link
          style="margin: 0 16px"
          :to="item.name.toLowerCase()"
          v-if="maxNavItems == 0 || index < maxNavItems"
        >{{item.name}}</router-link>
      </div>
      <select v-model="selected" ref="dropdown">
        <option disabled value="default">Please select one</option>
        <option v-for="(item, index) in getDropdownItems()" :key="`nav-${index}`">{{item.name}}</option>
      </select>
    </nav>
  </div>
</template>

<script>
export default {
  name: "app",
  data: () => ({
    groups: [
      { name: "NavItem1" },
      { name: "NavItem2" },
      { name: "NavItem3" },
      { name: "NavItem4" },
      { name: "NavItem5" },
      { name: "NavItem6" },
      { name: "NavItem7" },
      { name: "NavItem8" },
      { name: "NavItem9" },
      { name: "NavItem10" }
    ],
    width: "",
    maxNavItems: 0,
    selected: "default"
  }),
  async mounted() {
    await this.$nextTick();
    this.width = this.$refs["nav"].offsetWidth;

    let childrenTotalWidth = 0;

    for (let i = 0; i < this.$refs["nav"].children.length; i++) {
      const child = this.$refs["nav"].children[i];
      childrenTotalWidth += child.offsetWidth;
      if (childrenTotalWidth > this.width) {
        this.maxNavItems = i - 1;
        break;
      }
    }
  },
  methods: {
    getDropdownItems() {
      const newArr = [];
      for (let i = this.maxNavItems; i < this.groups.length; i++) {
        newArr.push(this.groups[i]);
      }
      return newArr;
    }
  }
};
</script>

<style>
#app {
  margin: 60px;
}

.link {
  display: inline-block;
  padding: 10px;
}

.router-link-active {
  color: green;
}
</style>

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

The size of objects on canvas is not consistent when loading with fabric.js loadFromJSON

Click here to view the code var canvas = new fabric.Canvas('canvas_1'); var canvas2 = new fabric.Canvas('canvas_2'); var imgObj = new Image(); imgObj.src = "https://gtaprinting.ca/wp-content/uploads/2021/05/blank-t-shirt-front-gre ...

Automate the execution of webdriver/selenium tests when a form is submitted

I am currently faced with a challenge in setting up an application that will automate some basic predefined tests to eliminate manual testing from our workflow. The concept is to input a URL via a user-friendly form, which will then execute various tests ...

Is there a more effective approach to managing an array of objects retrieved from an API call?

I'm attempting to extract an array of names from a JSON response that contains an array of objects, but I'm running into issues. When I try to print the array, it shows up empty. Is this the correct way to go about it? There don't seem to be ...

Production environment experiences issues with Angular animations

In my MEAN stack application, I started with Sails.js. Everything was working smoothly during development, especially with angular-animate. However, once I changed the Sails environment to production, I encountered issues. Grunt is set up to concatenate a ...

Removing a dynamic component in Angular

Utilizing Angular dynamic components, I have successfully implemented a system to display toaster notifications through the creation of dynamic components. To achieve this, I have utilized the following: - ComponentFactoryResolve - EmbeddedViewRef - Ap ...

Why is my npm installation generating an ERESOLVE error specifically linked to karma-jasmine-html-reporter?

Could someone help me understand this dependency error I encountered while running npm install and provide guidance on how to resolve such errors? View Error Screenshot I am currently using Angular 16, the latest stable version. npm ERR! code ERESOLVE ...

Include a novel item into the JSON string that is being received

Recently, I attempted to parse an incoming JSON string and insert a new object into it. The method I used looked like this: addSetting(category) { console.log(category.value); //Console.log = [{"meta":"","value":""}] category.value = JSON.parse(c ...

Updating the value of a v-text-field in Vuetify

What is the best way to modify input values? Here is an example: `https://jsfiddle.net/mbqjp4ax/` If a number entered is greater than 5, the system should automatically input the number 9 instead. While this works correctly when entering numbers greater ...

I am looking for a specific task to be carried out, without any need for returning a value or any additional items

I am trying to remove an element from the canvas using Selenium. The command I am currently using is "window.app.design.internalLayer().find('.deletebutton').fire('click')". Despite my efforts, this command does not seem to be working a ...

Maximizing Efficiency: Utilizing a Single Panel across Multiple HTML Files with jQueryMobile

Can a panel defined in index.html be used on another page, such as results.html? Or do I have to define the panel on every page and duplicate the HTML code on each page? Because I want the panel to be consistent across all pages. This is the panel in my ...

Utilize esbuild to monitor for any modifications, recompile the code, and automatically restart the express server

In my endeavor to develop a basic SSR-powered project using express + react, I find the need to monitor frontend and backend scripts concurrently in the development process. The primary objective is to utilize express routes in directing to react page com ...

Transmitting video through a local area network

I am seeking a solution to stream video content to a local network with potentially over 1000 viewers. The streaming will need to be accessible via web browsers such as Internet Explorer, Chrome, and Firefox, as not all users have internet access due to co ...

Can VueJS 1 and 2 be integrated within the same package.json configuration?

At the moment, my JavaScript files are using VueJS 1. However, I am preparing to work on a new section of the system and want to switch to VueJS 2. ...

What is the process for integrating an array of objects into Vue.js data?

Can someone assist me with setting data in Vue by using $set? I have gone through the documentation on vuejs.org but am unsure of what index to use with $set when my data is already null. Additionally, I am unclear about the correct syntax to use. Could ...

Can a link be generated that swaps out the original URL redirect for the following visitor upon clicking?

Can the program be fed with a list of links to automatically redirect to the next URL once clicked? In this setup, each visitor would only see one link and not have access to any other URLs in the chain. Is there a way to make this happen? Any suggestion ...

Unexpected behavior encountered with JQueryUI modal functionality

Today marks my first experience with JqueryUI. I am attempting to display a conditional modal to notify the user. Within my ajax call, I have this code snippet: .done(function (result) { $('#reportData').append(result); ...

Alert received upon selecting the React icon button

In the login code below, I have utilized FaEye and FaEyeSlash react icons. However, every time I click on them, a warning message pops up. To avoid this issue, I attempted to switch from using tailwindcss to normal CSS. Login.jsx import { useContext, useS ...

Is there a way to imitate a method that initiates an AJAX request?

I am currently working on writing tests for my Angular application and I need to mock a method in order to avoid making actual requests to the server. Within my grid.service.ts file, here is the method I am trying to mock: loadAccountListPromise(id: str ...

Unable to bind to property as it is not recognized as a valid attribute of the selector component

I have a situation where I need to pass a variable from one component to another using @input. Here is my parent component : @Component({ selector: 'aze', templateUrl: './aze.component.html', styleUrls: [('./aze.compo ...

I'm curious if there is a method to determine the status of a .net required field validator using JavaScript

I am attempting to determine the status of the "required field validators" within an .aspx file. By state, I am referring to whether they are enabled or disabled rather than if their contents are valid or invalid. I am aware that the enabled/disabled sta ...