Reece
Reece

Reputation: 2701

Vue $emit not firing inside parent

For some reason my $emit doesn't seem to be firing inside the parent. I am basically trying to create a modal popup for a html form. Inside my header component I have a button that fires $emit I then try to listen to this event inside my app.js on the form component. But the form component is doing nothing when the emit is fired.

Here's my code

client/src/app.js

<template>
    <div id="app">
        <MainHeader :modalVisability="modal" />
        <OppForm :modalVisability="modal" v-on:showModal="modal = $event"/>

        <div>{{ modal }}</div>
    </div>
</template>

<script>
import MainHeader from './components/MainHeader.vue';
import OppForm from './components/oppForm.vue';

export default {
    name: 'App',
    components: {
        MainHeader,
        OppForm
    },
    data() {
        return {
            modal: false
        }
    }
}
</script>

client/components/MainHeader.vue

<template>
    <div id="main_header_wrap">
        <header>
            <button v-on:click="showOppForm">Add Post</button>
        </header>

        <div>{{ modalVisability }}</div>
    </div>
</template>

<script>
    export default {
        props: {
            modalVisability: Boolean
        },
        methods: {
            showOppForm() {
                this.modalVisability = true;
                this.$emit('showModal', this.modalVisability);
            }
        },
    }
</script>

client/src/components/oppForm.vue

<template>
    <div id="opp_form" >
        <form @submit.prevent="SubmitOpp" v-if="modalVisability">
            <input type="text" name="company_name" v-model="company_name">
            <button type="submit">Submit</button>
        </form>

        <div>{{ modalVisability }}</div>
    </div>
</template>

<script>
    import axios from 'axios';

    export default {
        name: 'oppForm',
        props: {
            modalVisability: Boolean,
        },
        data() {
            return {
                company_name: ''
            }
        },
        methods: {
            SubmitOpp() {
                axios.post('http://localhost:5000/', {
                    company_name: this.company_name,
                })
                .then(function (response) {
                    console.log(response);
                })
                .catch(function (error) {
                    console.log(error);
                });
            }
        }
    }
</script>

Upvotes: 1

Views: 54

Answers (1)

Gabriel Willemann
Gabriel Willemann

Reputation: 1921

I fixed somethings in your code. See the example below:

client/src/app.js

<template>
  <div id="app">
    <MainHeader :modalVisability="modal" @showModal="changeModal" />
    <OppForm :modalVisability="modal" />
    <div>App = {{ modal }}</div>
  </div>
</template>

<script>
import MainHeader from './components/MainHeader.vue';
import OppForm from './components/oppForm.vue';

export default {
  name: 'App',
  components: { MainHeader, OppForm },
  data() {
    return {
      modal: false,
    };
  },
  methods: {
    changeModal(newValueModal) {
      this.modal = newValueModal;
    },
  },
};
</script>

client/components/MainHeader.vue

<template>
  <div id="main_header_wrap">
    <header>
      <button v-on:click="showOppForm">Add Post</button>
    </header>
    <div>MainHeader = {{ modalVisability }}</div>
  </div>
</template>

<script>
export default {
  props: {
    modalVisability: Boolean,
  },
  methods: {
    showOppForm() {
      this.$emit('showModal', !this.modalVisability);
    },
  },
};
</script>

client/src/components/oppForm.vue

<template>
  <div id="opp_form">
    <form @submit.prevent="SubmitOpp" v-if="modalVisability">
      <input type="text" name="company_name" v-model="company_name" />
      <button type="submit">Submit</button>
    </form>
    <div>oppForm = {{ modalVisability }}</div>
  </div>
</template>

<script>
import axios from 'axios';

export default {
  name: 'oppForm',
  props: {
    modalVisability: Boolean,
  },
  data() {
    return {
      company_name: '',
    };
  },
  methods: {
    SubmitOpp() {
      axios
        .post('http://localhost:5000/', {
          company_name: this.company_name,
        })
        .then(function(response) {
          console.log(response);
        })
        .catch(function(error) {
          console.log(error);
        });
    },
  },
};
</script>

1 - App.js: Listen the event in MainHeader component.

2 - App.js: OppForm don't need to listen the event, because this component don't change the modal value.

3 - MainHeader.vue: Avoid to change the props value.

Upvotes: 1

Related Questions