Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

Como usar uma variável compartilhada entre os componentes

Pessoal talvez a dúvida seja bem simples, mas não consegui achar uma solução.

Tenho um componente pai que contem uma DIV. Essa DIV tem a informação de um parceiro, então desenvolvi um componente MODAL para quando clicar na DIV o modal ficar visível com as informações daquele cliente. Até ai tudo bem, porém não consigo mais fazer o componente ficar invisível.

Componente Pai

<template>
  <div>
    <div @click="showModal = true" class="itemParceiro shadow p-3 mb-5">
      <img src="@/assets/parceiros/museu_automovel.png" alt="logo" />
      <span>Nome Parceiro</span>
    </div>

    <transition name="modal">
      <ModalParceiro v-if="showModal" :showModal="showModal"/>
    </transition>
  </div>
</template>

<script>
import ModalParceiro from '@/components/ModalParceiro.vue';
export default {
  data() {
    return {
      showModal: false
    };
  },
  components:{
    ModalParceiro  
  }
};
</script>

<style scoped>
.itemParceiro {
  height: 250px;
  width: 200px;
  margin: 10px;
  text-align: center;
}
.itemParceiro img {
  height: 100px;
  width: 180px;
}

.modal-enter-active, .modal-leave-active {
  transition: opacity .5s;
}
.modal-enter, .modal-leave-to /* .fade-leave-active em versões anteriores a 2.1.8 */ {
  opacity: 0;
}
</style>

Componente Filho

<template>
    <modal>
      <div class="modal-mask">
        <div class="modal-wrapper">
          <div class="modal-container">
            <div class="modal-header">
              <span>default header</span>
              <button @click="showModal = false" type="button" class="close">
                <span >&times;</span>
              </button>
            </div>
            <div class="modal-body">
              <p>default body</p>
            </div>
            <div class="modal-footer">
              <p>default footer</p>
            </div>
          </div>
        </div>
      </div>
    </modal>
</template>

<script>
export default {
    props:{
        showModal: Boolean
    }
}
</script>

<style scoped>
.modal-mask {
  position: fixed;
  z-index: 9998;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  display: table;
}

.modal-wrapper {
  display: table-cell;
  vertical-align: middle;
}

.modal-container {
  width: 600px;
  margin: 0px auto;
  padding: 20px 30px;
  background-color: #fff;
  border-radius: 5px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.33);
}
</style>
3 respostas
solução!

Fala ai Tainan, tudo bem? Uma das maneiras que você pode resolver esse problema, é passar uma função para o componente ModalParceiro para que seja chamada quando o usuário fechar o modal.

Sendo assim, essa função vai mudar o valor da variável showModal de true para false (no componente pai), uma vez que ela voltar a ser false a condição v-if="showModal" não será válida e o mesmo provavelmente vai fechar.

Seria algo mais ou menos assim:

<template>
  <div>
    <div @click="showModal = true" class="itemParceiro shadow p-3 mb-5">
      <img src="@/assets/parceiros/museu_automovel.png" alt="logo" />
      <span>Nome Parceiro</span>
    </div>

    <transition name="modal">
      <ModalParceiro v-if="showModal" :showModal="showModal" :closeModal="toggleShowModal"/>
    </transition>
  </div>
</template>

<script>
import ModalParceiro from '@/components/ModalParceiro.vue';
export default {
  data() {
    return {
      showModal: false
    };
  },
  components:{
    ModalParceiro  
  },
methods: {
    toggleShowModal() {
        this.showModal = !this.showModal;
    }
}
};
</script>

<style scoped>
.itemParceiro {
  height: 250px;
  width: 200px;
  margin: 10px;
  text-align: center;
}
.itemParceiro img {
  height: 100px;
  width: 180px;
}

.modal-enter-active, .modal-leave-active {
  transition: opacity .5s;
}
.modal-enter, .modal-leave-to /* .fade-leave-active em versões anteriores a 2.1.8 */ {
  opacity: 0;
}
</style>
<template>
    <modal>
      <div class="modal-mask">
        <div class="modal-wrapper">
          <div class="modal-container">
            <div class="modal-header">
              <span>default header</span>
              <button @click="closeModal" type="button" class="close">
                <span >&times;</span>
              </button>
            </div>
            <div class="modal-body">
              <p>default body</p>
            </div>
            <div class="modal-footer">
              <p>default footer</p>
            </div>
          </div>
        </div>
      </div>
    </modal>
</template>

<script>
export default {
    props:{
        showModal: Boolean,
    closeModal: Function
    }
}
</script>

<style scoped>
.modal-mask {
  position: fixed;
  z-index: 9998;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  display: table;
}

.modal-wrapper {
  display: table-cell;
  vertical-align: middle;
}

.modal-container {
  width: 600px;
  margin: 0px auto;
  padding: 20px 30px;
  background-color: #fff;
  border-radius: 5px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.33);
}
</style>

Pode ser que seja necessário alguma modificação, mas, a ideia é mais ou menos essa.

Espero ter ajudado.

Eu não fazia ideia que dava pra passar uma function como props. Muito boa a dica, vai ser muito util.

Magina Tainan, sempre que precisar não deixe de criar suas dúvidas.

Abraços e bons estudos.

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software