Home > OS >  Vue can't receive subscribe to event from child component in to parent component
Vue can't receive subscribe to event from child component in to parent component

Time:01-15

I have two components - parent and child. The child emits an event, which should trigger a console output in a parent component. However nothing is printed in console.

TestPage.vue:

<template>
  <div v-on:hidden="hiddenEvent">

    <TestComponent></TestComponent>
  </div>
</template>

<script>

import TestComponent from "@/app/test/TestComponent";
export default {
  name: "TestPage",
  components: {TestComponent},


  methods:  {
    hiddenEvent()  {
      console.log("hiddenEvent");
    }
  }
}
</script>

<style scoped>

</style>

TestComponent.vue:

<template>
  <div  v-if="!isHidden"
        v-on:click="this.flip">
    {{this.text}}
  </div>
</template>

<script>
export default {
  name: "TestComponent",

  data() {
    return {
      text: "abc",
      isHidden: false
    }
  },

  methods:  {
    flip()  {
      this.isHidden = !this.isHidden;

      if (this.isHidden)  {
        this.$emit("hidden");
      } else  {
        this.$emit("revealed");
      }
    }
  }
}
</script>

<style scoped>

.test-container  {
  padding: 2em;

  background-color: #2EAC68;
}

</style>

When I click on the abc:

enter image description here

it disappears:

enter image description here

So I know the flip method is executed. However the parent's hiddenEvent is not executed, because hiddenEvent is never printed to console.

What am I doing wrong? I need the parent TestPage to be able to react to the event emitted by the child TestComponent

CodePudding user response:

You should use v-on:hidden="hiddenEvent" on TestComponent tag not on the wrapping div.

The

<TestComponent></TestComponent>

in TestPage.vue should be updated to:

<TestComponent v-on:hidden="hiddenEvent"></TestComponent>

See in sandbox

CodePudding user response:

You are listening to event from the child so put it on the child:

const app = Vue.createApp({
  methods:  {
    hiddenEvent()  {
      console.log("hiddenEvent");
    }
  }
})
app.component('testComponent', {
  template: `
    <div  v-if="!isHidden"
        v-on:click="this.flip">
    {{this.text}}
  </div>
  `,
  data() {
    return {
      text: "abc",
      isHidden: false
    }
  },
  methods:  {
    flip()  {
      this.isHidden = !this.isHidden;
      if (this.isHidden)  {
        this.$emit("hidden");
      } else  {
        this.$emit("revealed");
      }
    }
  }
})
app.mount('#demo')
.test-container  {
  padding: 2em;
  background-color: #2EAC68;
}
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<div id="demo">
  <div >
    <test-component @hidden="hiddenEvent"></test-component>
  </div>
</div>

  • Related