Improving Vue Method with Lodash?

In one of my Vue components, I have implemented logic in the watch prop that allows for sequential switching between elements when the down arrow key (key code 40) is pressed. While it is not too messy right now, there is a concern that it may become highly inefficient in the long run. Here is the current structure:

data () {
 return {
  firstElActive: true,
  secondElActive: false,
  thirdElActive: false
  ...
 }

},

props: {
 nextEl: {
  type: Boolean,
  default: false,
  required: true
 }
},

watch: {
 nextEl: function (value) {
  if (this.nextEl) {
   if (this.firstElActive) {
    this.firstElActive = !this.firstElActive;
    this.secondElActive = !this.secondElActive;
    ... // other specific logic
   }
   else if (this.secondElActive) {
    this.secondElActive = !this.secondElActive;
    this.thirdElActive = !this.thirdElActive;
    ... // other specific logic
   }
   ... // and so on
  }
 }
}

It's evident that this approach may lead to complications as the codebase grows. I have Lodash globally available (window._ = require('lodash')) and wish to leverage it for refactoring. I'm currently exploring the most efficient methods to improve this. Any suggestions?

Answer №1

Opt for using a single active index instead of multiple boolean data properties. Increase or decrease the active index based on user interaction.

new Vue({
  name: 'example',

  data() {
    return {
      items: [
        { id: 0, value: 'item 1'}, 
        { id: 1, value: 'item 2'}, 
        { id: 2, value: 'item 3'},
      ],
      activeIndex: 0,
      arrowUpKeyCode: 38,
      arrowDownKeyCode: 40,
    };
  },

  computed: {
    currentItem() {
      return this.items[this.activeIndex];
    },
  },

  methods: {
    bindEvents() {
      document.addEventListener('keydown', this.onKeyDown);
    },

    unbindEvents() {
      document.removeEventListener('keydown', this.onKeyDown);
    },

    onPrev() {
      console.log(`on prev (key code ${this.arrowUpKeyCode}) ${this.currentItem.value}`);
    },

    onNext() {
      console.log(`on next (key code ${this.arrowDownKeyCode}) ${this.currentItem.value}`);
    },

    goPrev() {
      if (this.activeIndex > 0) {
        this.activeIndex -= 1;
        this.onPrev();
      }
    },

    goNext() {
      if (this.activeIndex < this.items.length - 1) {
        this.activeIndex += 1;
        this.onNext();
      }
    },

    onKeyDown(ev) {
      if (this.arrowUpKeyCode === ev.keyCode) this.goPrev();
      else if (this.arrowDownKeyCode === ev.keyCode) this.goNext();
    },
  },

  mounted() {
    this.bindEvents();
  },

  beforeDestroy() {
    this.unbindEvents();
  },
}).$mount('#example');
.active { background-color: dodgerblue; }
<script src="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="94e2e1f1d4a6baa1baa5a7">[email protected]</a>/dist/vue.js"></script>

<div id="example">
  <ul>
    <li v-for="(item, index) in items" 
        :key="item.id" 
        :class="{ active: index === activeIndex }">
      {{ item.value }}
    </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

Issues with IE7 related to Jquery and potentially HTML as well

I am currently working on a website project for a local charity organization, and I am encountering technical issues with compatibility in IE7. The website functions perfectly in all other browsers I have tested, and it even passes the validation process o ...

Next.JS is having trouble importing the URL class from the 'url' module in Node

Recently, while developing with next.js and webpack 5, I encountered an issue where my URL class import stopped working unexpectedly. Upon running npm run build, the following error message appeared: Attempted import error: 'URL' is not export ...

Restore Bootstrap Dropdown values to their initial settings when clicked

I need a button that can reset all filter dropdown values to their default values. The current code I have only changes all values to "Filter" when reset, but I specifically need it to reset to "Car brand" and "Model". Here's my code: // set.... $(" ...

Using dynamic variables in the $.getJSON function

This specific inquiry represents my current goal, with an added layer of complexity. My aim is to streamline the process by creating a single 'fetchData' function in my VueJS project that can retrieve multiple JSON files without duplicating code ...

What is the best way to save JSON data within HTML elements?

I want to enhance my FAQ by making it easily editable. Currently, the content can only be edited in the HTML file. I am looking to load all the information from a JSON file so that any changes or additions to questions and answers can be made directly in t ...

Attempting to access an avatar image via an API, only to encounter an error message indicating that the avatar is not defined

userData is a function that retrieves user data from an API using getUserByChainAccount. The username required by getUserByChainAccount is dynamically fetched from buyer. I'm trying to access the avatar, but I keep encountering the error message Unha ...

Advancing past the stage of developing basic functions in the document.ready() event handler

When I develop a website, I have a personal preference of creating a main JavaScript file with window.load and window.ready functions at the top. I find it easier to refactor any logic into separate functions within these functions for better readability. ...

VueJS - vue2-editor rejecting certain tags

I have successfully integrated the vue2-editor, and here is the code snippet: <div id="app"> <vue-editor v-model="content"></vue-editor> <div v-html="content"></div> </div> </t ...

Vue.js v-for dynamically creates HTML blocks that capture the state of collapse with two-way data binding

I am currently working on capturing the click action state within an HTML v-for generated block for a collapsible function. I have set up a data table and it seems that the state is being captured correctly. However, I am facing an issue where the displa ...

Tips for retrieving specific information from Wikipedia using AJAX

Is there a way to retrieve the information consistently displayed in the right box during searches using AJAX? I've tried using the Wikipedia API, but haven't been able to find the specific information I need. https://i.sstatic.net/wqJEc.png ...

When the HTML content matches a specific value, initiate a click event to trigger

Can anyone help me troubleshoot? I've tried multiple methods but can't seem to get it right. Here's a breakdown of what I'm attempting to accomplish: #info-NUMBER-btn shows Click to display more information. #info-NUMBER CSS is set t ...

Updating row color according to values obtained from the map function in ReactJs

I have been experimenting with various methods to change the color of table rows based on specific values within a map function. Despite trying solutions like the UseRef hook and browsing through stack overflow, I have yet to achieve success. {dat ...

Develop a personalized event that is compatible with all types of selectors

If I have a simple script that changes the background color of an element when clicked: $(".foo").on("change.color", function() { $(this).css("background-color", "red"); }); $(".foo").click(function() { $(this).trigger("change.color"); }); Currently ...

How can infinite watch loops be detected in Vuejs?

Currently, I am tackling a complex VueJS project and unfortunately made a significant error along the way. I mistakenly added a watch to a getter, triggering an action within the watch that modified the state and in turn called the getter reactively. This ...

What's the most efficient way to iterate through this Array and display its contents in HTML?

I'm struggling to sort a simple array and I think the issue might be related to the time format. I'm not sure how to reference it or how I can properly sort the time in this array format for future sorting. //function defined to input values ...

Having images that are too large in size and using a high percentage can

I'm encountering a strange issue. When I define the width and height of my images in pixels in my CSS file, all my jQuery animations and events work perfectly fine. However, when I switch to using percentages or 'auto' for the image dimensio ...

Unable to view Bootstrap Icons in Gulp 4

I recently integrated the new bootstrap icons npm package into my project using Gulp 4, the latest version. Everything was installed successfully and was working smoothly. However, I encountered an issue when trying to declare the icon in my index.html fi ...

Utilizing additional PHP files to handle the AJAX post request and subsequently execute the PHP script

I have been tasked with a complex assignment that I am struggling to comprehend. Let me provide a brief overview of what is required of me. There are three files involved in this task: 1. An HTML file that sends an AJAX post request to passwrapper.php. 2. ...

Pinterest's "Pin it" button causing issues with the 'back' function in Internet Explorer

Recently, I discovered a problem with the "Pin it" button for Pinterest in Internet Explorer (v9 at least). It seems that this button is causing issues with the 'back' functionality in the browser. When right-clicking on it, an entry like '& ...

I am curious as to why jQuery offers the done() method for promises, while the JavaScript promises documented by Mozilla do not. Is there a way to incorporate a done() method in vanilla JavaScript promises if needed?

What sets apart the Promises in Mozilla's JavaScript documentation (view API page) from those in jQuery's Promises (see API page)? It appears that Mozilla's promise only includes 2 methods: then and catch. On the other hand, jQuery's p ...