Tips for effectively reusing the modal component in Vue.js without encountering re-render issues

I'm encountering an issue where the same component content is being rendered despite having different components (Rendering problem).

I have a reusable modal component called modal.vue, so every time I create a new component, I call the modal component and inject new content into it.

The problem arises when I have two components (country.vue & city.vue) imported in my index.vue file.

Whenever I click on a button to load the city component, the country modal gets loaded instead, leading to a rendering problem (unable to re-render).

Could someone please explain the solution to this issue? Below is my code:

modal.vue (re-usable)

<template>
    <div class="right-bar" :class="(size == null) ? 'right-bar-35' : size">
      <simplebar class="h-100">
        <div class="rightbar-title px-3 py-4">
          <div class="row">
            <div class="col-lg-10">
              <h5 class="m-0">{{title}}</h5>
            </div>
            <div class="col-lg-2 text-right">
              <span class="clickable" @click="hideRightSidebar"><i class="mdi mdi-close-thick"></i></span>
            </div>
          </div>
        </div>
        <div class="px-3 py-4">
          <slot/>
        </div>
        <footer class="modal-footer">
          <button type="button" class="btn btn-secondary" style="float:left;">Cancel</button>
          <slot name="footer"/>
        </footer>
      </simplebar>
    </div>
</template>

As you can see, I have a <slot/> in my component to inject new content each time.


This is my country.vue component (using the modal.vue component)

<template>
    <div>
        <button class="btn btn-sm btn-white" @click="init">Filter <i class="mdi mdi-filter"></i></button>
        <modal title="countries" v-if="showModal">
               i 'am the country modal
        </modal>
    </div>
</template>
<script>
import RightBar from "@/components/modal";

export default {
    data() {
        return {
            showModal: false
        }
    },
    components:{
        modal,
    },
    methods: {
        init: function(){
            this.showModal= true;
        }
    }
}
</script>

This is my city.vue component (using the modal.vue component)

<template>
    <div>
        <button class="btn btn-sm btn-white" @click="init">Filter <i class="mdi mdi-filter"></i></button>
        <modal title="cities" v-if="showModal">
               i 'am the citymodal
        </modal>
    </div>
</template>
<script>
import RightBar from "@/components/modal";

export default {
    data() {
        return {
            showModal: false
        }
    },
    components:{
        modal,
    },
    methods: {
        init: function(){
            this.showModal= true;
        }
    }
}
</script>

This is my index.vue (where I load city.vue and country.vue) as you can see both of my components have a button

<template>
    <div>
       <city></city>
       <country></country>
    </div>
</template>
<script>
import addContact from "./city.vue";
import filterContact from "./country.vue";
export default {
    components:{city,country}
    data(){
        return {
        }
    }
}
</script>

Whenever I click on city, I encounter the country modal instead (rendering problem). How can I resolve this?

Answer №1

Consider this illustration:

Within the city and country component, include a function that notifies the parent component of an upcoming rerendering. Trigger this function upon clicking the show modal button.

init(){
  this.rerender()
  this.showModal= true
},
rerender(){
  this.$emit('forceRerender', true)
}

Subsequently, within the parent component, monitor this function to prompt a rerender.

<city v-if="isCountry" v-on:forceRerender="hideCountry" />
<country v-if="isCity" v-on:forceRerender="hideCity" />

data(){
  return{
    isCountry: true,
    isCity: true,
  }
},
methods:{
  hideCountry(){
    this.isCountry= false
    this.$nextTick(()=>{
      this.isCountry= true
    })
  },
  hideCity(){
    this.isCity= false
    this.$nextTick(()=>{
      this.isCity= true
    })
  }
}

The concept here is that when loading the modal from the city component, we instruct the country component to first close its modal. Hopefully, this approach proves effective for you.

An alternative method using a switch statement follows:

For the city component:

rerender(){
  this.$emit('forceRerender', 'city')
}

Regarding the country component:

rerender(){
  this.$emit('forceRerender', 'country')
}

In the parent component:

<city v-if="isCountry" v-on:forceRerender="setActiveElement" />
<country v-if="isCity" v-on:forceRerender="setActiveElement" />

setActiveElement(element){
  switch(element){
    case 'city':
      this.isCity = true
      this.isCountry = false
      this.$nextTick().then(()=>{
        this.isCountry = true
      })
      break
    case 'country':
      this.isCountry = true
      this.isCity = false
      this.$nextTick().then(()=>{
        this.isCity= true
      })
      break
    default: 
      this.isCountry = this.isCity = true
      break
  }
}

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 does not function upon reloading the browser

I am currently working on a new project that involves the following components: Node.js (v0.10.37) Express micro framework Jade templating engine Angular.js (latest) Material design library (material.angularjs.org) Jquery One issue that I am facing is r ...

In search of a versatile multi-slide carousel solution for Angular JS

Hello everyone, we are looking to implement a carousel in our project. I came across the angular-carousel while searching online and found this helpful link http://www.bootply.com/94452. However, the carousel is written in jQuery and we will not be using ...

Guidelines for sending data as an array of objects in React

Just starting out with React and I have a question about handling multi select form data. When I select multiple options in my form, I want to send it as an array of objects instead of an array of arrays of objects. Can anyone help me achieve this? import ...

Error in Blinking Tooltip when Hovering Skill Bubble (React and d3)

I've encountered a frustrating issue with tooltips on my website - they just won't stop blinking when I hover over the skill bubbles. I tried fixing the tooltips at a certain location, but whenever there's a bubble in that spot and I hover o ...

Moving data from one table to another and making changes or removing it

After successfully adding data from one table to another using .click, I encountered an issue. Whenever I utilize the search field in the top table, it clears the appended rows in the bottom table. I am looking for a solution to have these tables generate ...

Add some TD(s) after the td element

The HTML code I currently have is as follows: <tr> <td class="success" rowspan="1">Viability</td> <td data-rowh="-Checksum">Viability-Checksum</td> </tr> <tr> ...

Request with content Type multipart/form experienced Error 406

I encountered an issue with my axios request in Express const formData = new FormData(); formData.append("file", fs.createReadStream(file.path)); formData.append("requestid", '123456'); const options = { method: 'POST& ...

show the day of the week for a specific date saved in a MongoDB database

I need to create a report showing the total number of purchases for each day in the past week, formatted like this: { "sunday":30, "monday":20, ... } Each purchase in the database is structured as follows: { _id: 603fcb ...

Error with NEXTJS: Prop type failed - The prop `href` in `<Link>` is expecting a `string` or `object`, but received `undefined`

After importing the Link from next/link and attempting to pass the dynamic endpoint in my components, I encountered an error message. https://i.stack.imgur.com/eqUK8.png https://i.stack.imgur.com/eIC4V.png I searched for a solution and came across a sug ...

Displaying 2 unique div elements with distinct buttons on a single blade using Laravel and VUE

Hello everyone! I have a puzzle for you: I possess one blade, but when I am given two distinct buttons: <div class="col-md-12"> <button v-on:click="isHidden = !isHidden" type="button" class="w3-btn ...

Continuously update in JavaScript based on a condition, cease updating when the condition no longer

I have a scenario on my page where specific data needs to be refreshed every minute, but at the same time, the user should be able to view and edit certain modals. I want to ensure that when a modal is open, the data refreshes are paused so that the modal ...

Adjust columns sizes on ExtJS 6 dashboards in real-time

Is it possible to adjust the column widths within an Ext.dashboard.Dashboard once it has been displayed? The initial configuration sets the column widths as follows: columnWidths: [ 0.35, 0.40, 0.25 ] I would like to dynamically modify them ...

Combining 3 Vue.js elements into 1 element with true/false active toggling

When one element is true, the button should also be true. When one element is false, the button should still be true. But when all three elements are now selected, the button should be false. I have 3 elements where clicking on one of them should make the ...

Can a node.js file be exported with a class that includes IPC hooks?

[Node.js v8.10.0] To keep things simple, let's break down this example into three scripts: parent.js, first.js, and second.js parent.js: 'use strict'; const path = require('path'); const {fork} = require('child_process&apo ...

Exploring the potential of utilizing functions in express.js to take advantage of the "locals"

Having experience with Rails/Sinatra, I am accustomed to using helper functions in my view files. However, incorporating this functionality into express.js has proven to be quite challenging. You can include locals automatically like this... app.set("nam ...

Why does the jQuery .each loop only loop when I console.log?

Feeling a little confused right now. I have a .each function that successfully displays all results from JSON when I use console.log, but for some reason, when I try to output using .html(), it only shows one result at a time. Any idea why this might be ha ...

What could be causing my tab code to not function flawlessly?

I am attempting to implement a tab concept on my website. For example, the tab names are Monday...Tue.. up to Sunday. Each tab contains an image file based on the days (size 460*620). When I run my page, it shows all images, but what I need is for the imag ...

A guide to updating property values in an array of objects in JavaScript while ensuring they remain in consecutive order

I am dealing with an array of objects called list. The parameters rid and rorder are provided for processing. -> 1. Whenever the value of rid matches the id in the list, the itemorder is updated with the value of rorder. -> 2. In the updated list p ...

unable to display picture on puggy

Check out the code snippet below: <!DOCTYPE html> <html lang="en> <head> <meta charset="UTF-8> <title>Home Page</title> </head> <body> <img src="resources/mainlogo.png" style="width:304px;height:2 ...

Is there a way to determine whether a mouse-down event took place on the scroll-bar or elsewhere within the element?

Looking for a solution with my HTML div acting as a canvas containing various objects. The issue lies in the fact that when attempting to draw a selection rectangle by dragging with the mouse, if scroll bars appear due to the large size of the canvas, scr ...