0

I'm opening the same component content since i have a different ones, ( Rendering problem )

I have a modal component called modal.vue (Re-usable) so each time I create a component I call the modal component and I inject new content,

The problem is : I have two-component ( country.vue & city.vue ) I import both of them in my index.vue

but each time I click on a city button to load city component, I load the country modal, just like there is a rendering problem ( i can't re-render )

can someone explain to me the solution please, this 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 so each time in inject a new content.


This is my country.vue component ( i use here 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 ( i use here 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 & 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>

So when i click on city i see the country modal ( re-rendering problem ) how can i solve that

3
  • is this how its suppose to look like? codesandbox.io/s/kind-khorana-pphhu?file=/src/components/… Commented Jun 27, 2021 at 17:51
  • create your code on sendbox and send your link here. I might be able to help you. get over here. stack overflow doesn't like commenting alot chattory.com/?chat=891742 Commented Jun 27, 2021 at 17:58
  • @RuthDavis Please don't post duplicate questions to give your question a bump or to add details. You can simply edit your original question next time. Commented Jun 28, 2021 at 5:26

1 Answer 1

1

Here's an example:

in city and country component add a function that tells the parent component that there will be a rerendering. you call this function once you click on the show modal button.

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

then in the parent component we'll listen to this function and 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= ture
    })
  },
  hideCity(){
    this.isCity= false
    this.$nextTick(()=>{
      this.isCity= ture
    })
  }
}

to break it down. when we want to load the modal from the city component we tell the country component to close the modal first. I hope this works for you.

another way with a switch statement:

city:

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

country:

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

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
  }
}
Sign up to request clarification or add additional context in comments.

2 Comments

looking for a clean way :(, what if i have 5 modals i have to repeat the same functions ?
you could do it in one single function if you want. it only requires returning the active element from the child component and then one function that contains a switch statement to filter which component to rerender

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.