Subscribe on changes!

When templates are compiled at runtime, kebab-cased event names specified in `emits` don't prevent event listeners from being passed down via $attrs

avatar
Nov 2nd 2020

Version

3.0.2

Reproduction link

https://codesandbox.io/s/reverent-wiles-u85ur?file=/src/main.js:140-160

Steps to reproduce

Having the code from the reproduction link:

import * as vue from "vue/dist/vue.esm-bundler.js";

const Inner = {
  template: `
    <button @click="logAttrs">log $attrs</button>
  `,
  emits: ["my-event"],
  methods: {
    logAttrs() {
      console.log(this.$attrs);
    }
  }
};

const App = {
  components: {
    Inner
  },
  template: `
    <Inner @my-event="noop" />
  `,
  methods: {
    noop() {}
  }
};

vue.createApp(App).mount("#app");
console.log({ "vue.version": vue.version });

click the log $attrs button to log this.$attrs.

What is expected?

this.$attrs should be empty since according to the docs placing event name in emits should prevent a listener for the event to fallthrough.

What is actually happening?

this.$attrs contains onMyEvent listener which means emits doesn't block it from being passed down.


Note: everything works as expected when templates are precompiled.

avatar
Nov 2nd 2020

Source of the problem is the same as #2540

Will close this as a duplicate