Discover the magic of triggering events that dynamically alter CSS styles

I am trying to implement an eventBus in the App.vue component that allows me to change a modal's CSS based on a payload object. For example, if I pass { type: 'success' }, the border of the modal should turn green, and if I pass { type: 'danger' }, it should turn red. Here is how I'm calling it:

 EventBus.$emit('call-modal', { type:'success' });

The challenge I'm facing is figuring out how to dynamically change the CSS of the modal based on the payload received through the eventBus. Can anyone help me achieve this functionality?

Below is a snippet of my sample component:

<template>
  <div>
   <button class="pleeease-click-me" @click="callModal()">Click me</button>
   <div class="modal" v-show="showModal">
     <h2>Message</h2>
   </div>
  </div>
</template>

<script>
import { EventBus } from '../App.vue';

export default {
  name: 'bankAccount',
  props: ['modalType'],
  data() {
    return {
      showModal: false
    }
  },
   methods: {
    callModal() {
      this.showModal = !this.showModal
      // Emitting an event with a payload when the button is clicked
      EventBus.$emit('call-modal', {type:'success'});
    }
  }
}

</script>

<style scoped>

.modal {
  height: 100px;
  width: 300px;
  border: solid gray 2px;
}
</style>

And here is a snippet of my App.vue component:

<template>
  <div id="app">

  <bankAccount/>
  </div>
</template>

<script>
import bankAccount from './components/bankAccount.vue'
import Vue from 'vue';
export const EventBus = new Vue();


EventBus.$on('call-modal', (type) => {

})

export default {
  data() {
   modalTypes = [
     { type: 'success' },
     { type: 'danger' },
   ]
  },
  name: 'app',
  components: {
    bankAccount
  },
}
</script>

<style>

</style>

Answer №1

Start by placing your modal component directly in the App.vue file. Define data properties like showModal and modalType within the component to store information about the modal. In the created hook, listen for call-modal events and update the data properties accordingly. Remember to apply the appropriate class based on the value of modalType. That's all it takes.

<template>
  <div id="app">
    <bankAccount />
    <div :class="['modal', `modal--type--${modalType}`]" v-show="showModal">
      <h2>Message</h2>
    </div>
  </div>
</template>

<script>
import bankAccount from './components/bankAccount.vue'
import Vue from 'vue'
export const EventBus = new Vue()

export default {
  name: 'app',
  components: {
    bankAccount,
  },
  data() {
    return {
      showModal: false,
      modalType: 'default',
    }
  },
  created() {
    EventBus.$on('call-modal', obj => {
      this.showModal = true
      this.modalType = obj.type
    })
  },
}
</script>

<style>
.modal {
  height: 100px;
  width: 300px;
  border: solid gray 2px;
}

.modal--type--success {
  border-color: green;
}
</style>

To trigger the modal, emit the 'call-modal' event using the EventBus.

EventBus.$emit('call-modal', { type: 'success' });

Answer №2

One essential step is to register and deregister the EventBus in your components.

This can be achieved either through using Vue.mixin for all components or by utilizing import in a single component:

<template>
  <div id="app">

  <bankAccount :class="modalTypes"/>
  </div>
</template>


<script>
import bankAccount from './components/bankAccount.vue'
import Vue from 'vue';
export const EventBus = new Vue();


EventBus.$on('call-modal', (type) => {

})

export default {
  data() {
   return {
     modalTypes = {
       'success': false,
       'danger': false
     }
   }
  },
  name: 'app',
  components: {
    bankAccount
  },
  created(){
    EventBus.$on('call-modal', this.callModal)
  },
  beforeDestroy(){
    EventBus.$off('call-modal', this.callModal)
  },
  methods: {
    callModal(evt){
      for(let key in this.modalTypes) 
        this.modalTypes[key] = key === evt.type
    }
  }
}
</script>

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

Exploring the ins and outs of HTML event handlers with JavaScript

When using events in your HTML and including a small amount of JavaScript, what is this called? Is it referred to as a "JavaScript attribute function," simply a "JavaScript attribute," or something else entirely? For example: <button onClick="locat ...

What is the process for managing items in an array within a separate file?

I am facing an issue where I need to display the 'title' object from an array in the document App.js. Everything works fine when I use an array without any objects: (before) App.js: import React from 'react' import TodoList from ' ...

Inquiry about how TypeScript handles object property references when passed into functions

As a newcomer to TypeScript, I am exploring the creation of a range slider with dual handles using D3.js. I have developed a simple class for managing the slider objects: export class VerticalRangeSlider{ private sliderContainer: d3.Selection<SVGG ...

typescript: define the type of an object that behaves like a map

My current approach involves utilizing an object to store a map, where keys are strings and values are of a fixed type T. Upon looking up a key in the object, the type inference automatically assigns it the type T. However, there is a possibility that it ...

Differences between const and let when utilizing the require function

With io.js now offering ES6 support, you can finally take advantage of the powerful const and let keywords. While let is seen as the successor to var with added capabilities, what about const? We all know what "constant" means, but when is it best practice ...

The element in TS 7023 is implicitly assigned an 'any' type due to the fact that an expression of type 'any' is not valid for indexing in type '{}'

I have implemented a select-box that includes options, labels, optgroups, and values. Is my approach correct or is there something wrong with the way I have defined my types? interface Option { label: string value: string selected?:boolean mainGrou ...

Ways to add a substantial quantity of HTML to the DOM without relying on AJAX or excessive strings

Currently, I am looking to update a div with a large amount of HTML content when a button on my webpage is clicked. The approach I am currently using involves the .html() method in JQuery, passing in this extensive string: '<div class="container-f ...

Dynamically inserting templates into directives

I've been attempting to dynamically add a template within my Angular directive. Following the guidance in this answer, I utilized the link function to compile the variable into an HTML element. However, despite my efforts, I haven't been success ...

Converting a Number from Negative to Positive in JavaScript and Representing it as 32 Bit Binary

I am facing an issue with converting a number to 32-bit binary data. While converting to 16 or 8 bits works fine, the result is incorrect when attempting to convert to 32 bits. For example, for 8 bits: -1 & 255 //result -> 255 or -1 & 0xFF //r ...

Tips for choosing multiple values from a dropdown menu in Bootstrap CSS version 3

I'm looking to implement a way to select multiple values from a dropdown menu without using the CTRL key. Currently, I am utilizing Bootstrap CSS for styling. Here is the code for my dropdown: <select multiple class="dropdown-menu"> ...

Sending AJAX Responses as Properties to Child Component

Currently, I am working on building a blog using React. In my main ReactBlog Component, I am making an AJAX call to a node server to get back an array of posts. My goal is to pass this post data as props to different components. One specific component I h ...

What is the reason for not allowing return statements in the ternary operator?

Imagine you have a basic form and you want to determine if the form has been modified. If it has changed, you want to submit it; otherwise, you want to prevent form submission. To tackle this, instead of using an if-else statement, I decided to go for a te ...

Is there a way to compel @keyframes to continue playing until it reaches its conclusion even after a mouseout event

Whenever I hover over an element, a keyframe animation starts playing. However, when I move the cursor away, the animation stops abruptly. Is there a way to ensure that it plays until the end? I've tried using the animationend event, but it doesn&apos ...

Can you use the OR operator between vee-validate3 rules?

For this input, the value can be either a username or email address. Here is an example: <ValidationProvider name="email" rules="username || email" v-slot="{ errors, valid }"> <v-text-field v-model="something" :error-messages="er ...

Methods for altering the color of a div using addEventListener

Why doesn't the color change when I click on the div with the class "round"? Also, how can I implement a color change onclick? var round = document.querySelector(".round"); round.addEventListener("click", function() { round.style.backgroundCol ...

Restart the _.after function counter

Despite my efforts to search online, I couldn't find a solution for resetting the _.after counter once the code inside has been executed. The goal here is to have the alert box appear only on every 5th click of the button: var cb; cb = _.after(4, fu ...

XMLHttpRequest Error: The elusive 404 code appears despite the existence of the file

This is the organization of my project files: The folders Voice, Text, and Template are included. https://i.stack.imgur.com/9un9X.png When I execute python app.py and navigate to localhost http://0.0.0.0:8080/, the index.html page is displayed with conte ...

Adding a dynamic key-value pair object to an array using the JS push method

In my programming challenge, I am dealing with an array of objects that have dynamic keys and values. The structure is a bit complicated, but here's a simplified version: let products_row = [ { id: 1, category_id: 11, options: { &a ...

In VueJS, the v-for directive allows you to access both parameters and the event object within

Imagine having nested elements that repeat using v-for in the following structure: <div id="container"> <div v-for="i in 3"> <div v-for="j in 3" v-on:click="clicked(i,j)"> {{i+&a ...

The error message "__vite_ssr_import_1__.Client does not have a constructor" is being displayed

Currently, I am working on a straightforward app that demonstrates CRUD operations using Appwrite and Nuxt 3 (Release Candidate 11). If you are interested, you can access the source code here. In my application, I am utilizing the landing page (index.vue) ...