What is the best way to conceal a div within every occurrence of a component when I activate my current target?

One of the challenges I'm facing involves displaying a div when a child component is clicked. This component is rendered multiple times on the page without any kind of loop. The tricky part is that when I show the div in one specific instance of the component, I want to hide it in all the other instances. I attempted to use a reference to close all instances through DOM manipulation, but unfortunately, that approach did not yield the desired outcome.

 <template>
  <span>
    <div class="options--small" @click="toggleOptions" />
    <div v-show="showOptions" ref="test" class="options-menu">
      <slot />
    </div>
  </span>
</template>
<script>
export default {
  name: 'ShowOptions',
  data () {
    return {
      showOptions: false
    }
  },
  methods: {
    toggleOptions () {
      this.$refs.test.style.display = 'none'
      this.showOptions = !this.showOptions
    }
  }
}
</script>

Answer №1

Avoid using ref or direct DOM access, as it should always be a last resort.

The visibility of each options menu is controlled by the showOptions property of the respective component. To communicate to every component instance to hide their menu, consider using an event bus. Implementing an event bus is recommended for Vue projects to enable decoupled inter-component communication.

If you are using Vue 2, a Vue instance can serve as an event bus.

Here is an untested example:

// event-bus.js

const v = new Vue()

export function on(event, fn) {
  v.$on(event, fn)
}

export function off(event, fn) {
  v.$off(event, fn)
}

export function emit(event, ...args) {
  v.$emit(event, ...args)
}
import * as bus from './event-bus.js'

export default {
  data() {
    return {
      showOptions: false
    }
  },
  created() {
    bus.on('ShowOptions.hide', this.onShowOptionsHide)
  },
  destroyed() {
    // Important otherwise leaks memory
    bus.off('ShowOptions.hide', this.onShowOptionsHide)
  },
  methods: {
    onShowOptionsHide() {
      this.showOptions = false
    },
    toggleOptions() {
      if (this.showOptions) {
        this.showOptions = false
      } else {
        bus.emit('ShowOptions.hide')
        this.showOptions = true
      }
    }
  }
}

If you prefer not to use an event bus, you can track every component instance to hide their menus.

Here is an untested example:

const instances = new Set()

export default {
  data () {
    return {
      showOptions: false
    }
  },
  created() {
    instances.add(this)
  },
  destroyed() {
    instances.delete(this)
  },
  methods: {
    hideOtherMenus() {
      for (const i of instances) {
        if (i !== this) {
          i.showOptions = false
        }
      }
    },
    toggleOptions() {
      this.hideOtherMenus()
      this.showOptions = !this.showOptions
    }
  }
}

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

Error encountered in thread "main": Issue with parsing string literal

import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; public class FindElementsUsingJS { static WebDriver driver= new FirefoxDriver(); public static void main(Stri ...

What's the best way to add a Grid to a TabPanel in React without triggering any pesky warnings?

I have a question that should be clear from the context. I'm currently working with Tabs from Material-UI to display different Grids based on the user's selection. Each panel is supposed to contain a Grid with various text fields and components. ...

In search of a fresh and modern Facebook node template

I've been on the hunt across the internet for a quality node.js Facebook template, but all I seem to stumble upon is this https://github.com/heroku/facebook-template-nodejs. It's okay, but it's built using express 2.4.6 and node 0.6.x. I wan ...

Fill up mongoose with data on 3 schemas

I have successfully populated 2 schema, but I am facing difficulty in populating the third schema. Here are the schemas: Member Schema var mongoose = require('mongoose'); var bcrypt = require('bcryptjs'); var Schema = mongoose.Schema ...

Unable to invoke a function in JavaScript

When I try to create a user in the database by calling the function createOne inside createProfile, it seems like the function is not getting executed. Even though the route is functioning properly, I'm facing an issue with calling a function within a ...

Using Vue.js to update a variable in a parent component that is nested multiple layers deep

Check out my cool Vue Instance: const myApp = new Vue({ el: '#my-app', data() { return { trigger: true } }, components: { ChildComponentOne, ChildComponentTwo }, router, store, ...

After the rendering of the HTML, the value of the jQuery input does not change

Here we have a function that loads HTML onto the form class in a file. The quest[q] locates the appropriate HTML template to load from an array of templates. The HTML being loaded contains an input with an id of "p". I am attempting to set the value of th ...

What are the steps to configure the datepicker with webdriverIO?

I am working on automating the booking.com page and I have successfully automated the process to open the calendar. However, I am now facing the challenge of selecting check-in and check-out dates. Can someone guide me on how to achieve this? Below is an ...

Share the Angular library distribution folder on a new git repository

I am faced with a dilemma regarding my Angular library that I often use in another project. The way I build my library is by running the command: ng build Upon executing this command, a dist/my-library directory is created at the library root. My goal is ...

Ionic timer binding issue: troubleshooting tips

Recently, I developed a stopwatch factory service that primarily focuses on running. Please disregard the reset and other functionalities as they are not yet implemented. Despite setting up $scope.time to capture timer changes, it doesn't seem to upd ...

Remove the class upon clicking

I recently created a toggle-menu for my website that includes some cool effects on the hamburger menu icon. The issue I am facing is that I added a JavaScript function to add a "close" class when clicking on the menu icon, transforming it into an "X". Whil ...

The window resizing function continues on an endless loop

I could really use some assistance in pinpointing the issue at hand! My script is set up to display a banner at the top of a page only if the window width is 600px or less and the scroll position is within 34px from the top. It hides the banner when the u ...

Instructions on utilizing slideDown() paired with appendTo()

I am looking to implement slideDown() alongside my appendTo() Below is the code I am currently using: $(document).ready(function() { var scntDiv = $('#add_words'); var wordscount = 1; $("#add_words").on("keyup","input[type='tex ...

How to effectively share an object array between controllers when utilizing modal windows in AngularJS

I'm currently working with an array of objects that I need to share between two controllers, one of which involves a modal window. Check out the JavaScript code below: angular.module('MyApp', ['ngMaterial', 'ngMessages' ...

AngularJS ng-view is a directive that views the application

I am currently struggling to create an angular js menu. I have been working on my code, but the pages are not loading as expected. Do you think I missed something or did I forget to include all the necessary scripts? I am fairly new to angular and could us ...

Personalize your material-ui popover

Seeking assistance in customizing the shape of a material-ui popover similar to the one depicted in the image. https://i.sstatic.net/l5uNL.png I have created a working demo of the popover using React and provided a link for editing purposes. Any help? =& ...

Issue with Javascript Promise causing failure to populate list with objects

app.get('/zones/:id/experiences', function(req,res) { var zone_key = req.params.id; var recent = []; var ref = firebase.database().ref('participants/'+zone_key+'/experiences'); ref.on("value", function(snapshot) { ...

In my experience, I have encountered issues with certain routes not functioning properly within Express

I am currently working on developing a tic-tac-toe game and looking to store user data in a database. However, I am facing an issue with the router I intended to use for this purpose as it is returning an 'Internal server error message (500)'. B ...

Unable to append item to JavaScript Map

Currently, I am attempting to insert an item into a Map (similar to a dictionary) using JavaScript within a React Native environment. import React, { Component } from 'react'; import { AppRegistry, View, Button, } from 'react-native& ...

Verify if there are duplicate values present in a table

I have a Table that contains multiple rows, each row having input fields. I need to check for duplicate values within the table. Below is my code where I am currently checking for empty values, how can I modify it to also detect duplicate values? JavaScr ...