Home > front end >  VueJS 3: Bare-bones $emit with v-if not working
VueJS 3: Bare-bones $emit with v-if not working

Time:04-26

I have two VueJS components, a parent and a child. What I'm trying to achieve here is a bare-bones emit example to serve as documentation and reference for later. At the push of a button, I would like a hidden message (v-if) to show up. At the moment, the button does nothing.

I have been searching the answer to this problem for the past hour and a half. I have looked at the official documentation, on YouTube and everywhere that seems relevant after a query a search engine. The answer to my question has to be quite simple, but somehow I can't seem to find it.

Parent

<template>
  <div >
    <img alt="Vue logo" src="../assets/logo.png">
    <HelloWorld msg="Welcome to Your Vue.js App"/>
  </div>

  <div @myEmit="handleEmit" v-if="show">
    show or not
  </div>
  <!-- <div>abcdef</div> -->
  <!-- <input type="text" @handleEmit="myEmit"> -->
</template>

<script>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue'

export default {
  name: 'HomeView',
  components: {
    HelloWorld
  },
  data () {
    return {
      show: false
    }
  },
  methods: {
    handleEmit () {
      this.show = true;
      console.log(this.show);
    }
  }
}
</script>

<style scoped>
  .home {
    background: lime !important;
  }
</style>

Child

<template>
  <div >
    <h1>{{ msg }}</h1>

    <button @click="handleClick">Click me</button>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  emits: ['myEmit', "test"],
  props: {
    msg: String
  },
  methods: {
    handleClick() {
      this.$emit('myEmit');
      this.$emit('test');
      console.log("emit event detected");
      // console.log(this.$emit);
    }
  }
}
</script>

<style scoped>
  .hello {
    background: pink;
  }
</style>

CodePudding user response:

The @myEmit is incorrectly applied to the <div> you want to conditionally show. The div does not emit the myEmit event, so your event handler would never be called.

The solution is to move the @myEmit to <HelloWorld>, which does emit the event:

<HelloWorld msg="Welcome to Your Vue.js App"/>

       ❌ div has no myEmit event
<div @myEmit="handleEmit" v-if="show">
  show or not
</div>
             ✅
<HelloWorld @myEmit="handleEmit" msg="Welcome to Your Vue.js App"/>

<div v-if="show">
  show or not
</div>

demo

  • Related