Why does $emit not work in my vue component

I see only one mistake here. You should add v-on to the child component. When you $emit('custom') from inside it will call "customHandler" on the parent component.

Working jsfiddle

<test-listen>
    <test-emit v-on:custom="customHandler"></test-emit>
</test-listen>

There are 2 things wrong here.

  1. Vue events can be bound to components only I guess (talking vue events here)
  2. Slots are not good with events. (Source - Evan You, Vue author)

If you really want to pass data here and there without restriction better to use Global Event Bus Approach

Working example of your code with some minor correction.

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="wrap">
  <test-listen>
  </test-listen>
</div>
<script>
Vue.component('test-listen', {
  data: function(){
    return {};
  },
  methods: {
    customHandler : function(e){
      console.log(e);
      console.log("works");
    }
  },
  template: `
    <div class='test_listen' >
      <test-emit v-on:custom="customHandler"></test-emit>
    </div>
  `
});

Vue.component('test-emit',{
  data: function(){
    return {};
  },
  methods: {
    clickHandler : function(e){
      // e => event : didnt pass here as console will stuck so
      this.$emit('custom', 'somedata');
    }
  },
  template : `
    <div class='test_emit' v-on:click="clickHandler">
      test
    </div>
  `
});

new Vue({
  el:"#wrap"
});
</script>
<style>
.test_listen{
  display:block;
  padding:20px;
  border:1px solid #000;
}
.test_emit{
  display:block;
  width:100px;
  height:100px;
  background-color:#f0f;
  color:#fff;
  font-weight:700;
  font-size:20px;
}
</style>

Tags:

Vuejs2