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

Eventos Customizados: do componente Filho para Pai

Tenho duas dúvidas sobre o método disparaAcao

disparaAcao() {
    if(this.confirmacao) {
        if(confirm('Confirma operacao?')) {
            this.$emit('botaoAtivado');
        }
        return;
    }
    this.$emit('botaoAtivado');
}

1) Idependente se confimacao for true ou false ele não irá emitir o evento this.$emit('botaoAtivado') ?

2) Qual a necessidade de usar o return dentro do if(this.confirmacao) ?

6 respostas

A lógica do código que você postou é a seguinte. Se não houver necessidade de confirmação, não entrará no if e this.$emit('botaoAtivado') será disparado.

Se o botão requerer confirmação, entrará dentro do if para que possamos exibir a tela de confirmação e saber se o usuário confirmou ou não. Se confirmar, dispara this.$emit('botaoAtivado'). Se não confirmar, não faz nada. Se confirmou ou não, logo em seguida tem um return que em lógica de programação indica que uma função esta retornando, no caso, não retornamos nada, apenas queremos parar sua execução.

Então, respondendo:

1) Idependente se confimacao for true ou false ele não irá emitir o evento this.$emit('botaoAtivado') ?

Se o botão estiver configurado para exibir a confirmação, só disparará o evento se ele confirmar.

2) Qual a necessidade de usar o return dentro do if(this.confirmacao) ?

Para sair imediatamente da função. Sem o return, sua função iria até o fim e dispararia o evento na última instrução, algo que não faz sentido se o usuário não clicou em confirmar..

Entendi!

Mas isso significa que se fizer dessa forma:

disparaAcao() {
    if(this.confirmacao)
        if(confirm('Confirma operacao?'))
            this.$emit('botaoAtivado');
}

Também funciona, correto? (aqui deu certo)

Inclusive, já que confirmacao só deve ser true quando o botão receber estilo="perigo", eu a transformei numa computed, assim:

computed: {
    estiloBotao() {
      if (this.estilo == 'padrao') return 'botao-padrao';
      if (this.estilo == 'perigo') return 'botao-perigo';
    },

    confirmacao() {
      if (this.estilo == 'perigo') return true;
    }
  }

Dessa forma, em Home.vue apenas é preciso especificar o estilo, e em Botao.vuea computed que resolve se deve ou não haver a confirmação.

Mas para que isso funcione é preciso alterar a props deixando estilo como obrigatório

props: {
    estilo: {
        required: true,
        default: 'padrao',
        type: String
    }
}

Já que estamos falando de botão, adorei saber que é possível utilizar duas props, uma usando v-bind e outra não.

<button class="botao" :class="estiloBotao">
    {{ rotulo }}
</button>

Dessa forma o botão fica genérico, e não precisa ficar repetindo class="botao".

Além disso, já que na props está como default o 'padrao' não há problema se o usuário omitir.

estilo: {
    required: true,
    default: 'padrao',
    type: String
}

Mas se ele colocar um estilo que não exista

<botao
    tipo="button"
    rotulo="apagar"
    :myPhoto="foto"
    @botaoAtivado="apagar(foto)"
    estilo="calopsita"
/>

O estilo do botão receberá apenas a classe botao e não botao botao-padrao.

Para sempre deixar como botao-padrao teria que fazer algo como isso, né?

computed: {
    estiloBotao() {
        if (this.estilo == 'perigo') return 'botao-perigo';
        else return 'botao-padrao';
    }
}

Não vai funcionar:

disparaAcao() {
    if(this.confirmacao)
        if(confirm('Confirma operacao?'))
            this.$emit('botaoAtivado');
}

Você tem que fazer o `this.$emit se o botão não requer confirmação, ou seja, se o usuário não quer fazer o popup de confirmação ser exibido. Pegou a ideia?

Acho que você esta confundido o this.confirmacao que é a propriedade que indica que o popup será exibido ou não com o a confirmação em si. Não?

Essa parte de enviar do componente filho para o pai é realmente complicada, mas deixa eu ver se entendi:

Independente de this.confirmacao ser true ou false é necessário fazer this.$emit('botaoAtivado') pois este evento serve para verificar se o botão foi acionado.

Porém, em alguns casos queremos que antes do botão ser acionado, haja uma confirmação do usuário através do pop up. Que é o caso do botão de remover foto. Para isso, passamos confirmacao como true.

É isso?

solução!

Isso mesmo! Mas se tiver confirmação, ai pode ou não emitir o evento. É que a ideia é que nem todo botão você quer exibir o popup, então por isso podemos indicar se queremos esse comportamento ou não. Sendo assim, um botão que não exibe o popup de confirmação por padrão já deve disparar o evento.