Behavior of custom events with same name, in parent and child compoents #8350
-
I'm trying to make a "BaseDialog" component for use to create "CustomDialog" components for different parts of the application. On this "BaseDialog", i have a footer with a "confirm button" that, when clicked, emit a "@confirm" custom event. On the "CustomDialog", i listen to this custom event and just emit to the parent a custom event with the same name "@confirm", because the parente component of "CustomDialog" is the one that will make something when this event is triggered. In resume, i have the following structure: BaseComponent <template>
<button @click="$emit('confirm', 'from base component')">
{{ text }}
</button>
</template> CustomComponent <template>
<BaseComponent
text="My button"
@confirm="$emit('confirm', 'from custom component')"
/>
</template>
<script>
import { defineComponent } from "vue";
import BaseComponent from "./BaseComponent";
export default defineComponent({
components: { BaseComponent },
});
</script> Parent component <template>
<CustomComponent @confirm="handleConfirm" />
</template>
<script>
import CustomComponent from "./components/CustomComponent.vue";
export default {
name: "App",
components: { CustomComponent },
methods: {
handleConfirm(event) {
console.log(event);
},
},
};
</script> What is the problem?
and the expected is only "from custom component". So, by the logic, the "ParentComponent" is listening to the custom event "@confirm" triggered by the both components: Base and Custom. However, if i wrap the "BaseComponent" in another tag (e.g. div), this same behavior do not happen, and in the console appear just "from custom component". <template>
<div>
<BaseComponent text="My button wrapped" @confirm="$emit('confirm', 'from custom component')" />
</div>
</template>
<script>
import { defineComponent } from "vue";
import BaseComponent from "./BaseComponent";
export default defineComponent({
components: { BaseComponent }
});
</script> The final question: is this behaviour (when the parent listen to a same event from nested components) already expected, or maybe this is a bug? Link for a codebox with the example: https://codesandbox.io/s/magical-bose-529zm4?file=/src/App.vue:0-713 |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
If you add the <CustomComponent @confirm="handleConfirm" /> =>
<template>
<button @click="$emit('confirm', 'from base component')">
{{ text }}
</button>
</template>
<script>
import { defineComponent,getCurrentInstance } from "vue";
export default defineComponent({
props: {
text: { type: String },
},
setup(){
const vm = getCurrentInstance()
console.log('cc',vm.attrs)
return {}
}
});
</script> You can view this print. |
Beta Was this translation helpful? Give feedback.
-
That's interesting! I had never paid attention on this behaviour of the attributes. After your comment, i found the liink in the documentation that explain this behaviour in details: https://vuejs.org/guide/components/attrs.html#attribute-inheritance Thanks for your answer! |
Beta Was this translation helpful? Give feedback.
If you add the
inheritAttrs: false
configuration option toCustomComponent
, you will find that only "from custom component" is printed. This is because components inherit attributes by default.=>