So I have this <Dialog />
component that extends vuetify's <v-dialog />
default.
In order to avoid having to pass a onClose
method to the DialogContent
component, I'd rather it $emit('close')
.
But I can't make my slot listen to this event. :(
Here's the code:
// Dialog.vue
<template>
<v-dialog
v-bind="$attrs"
v-model="dialog"
>
<!-- forward other slots -->
<template
v-for="(_, slot) of otherSlots"
v-slot:[slot]="scope"
>
<slot :name="slot" v-bind="scope" />
</template>
<template v-slot:default="{ on, attrs }">
<slot name="default" v-on="on" v-bind="attrs" @close="onClose" />
</template>
</v-dialog>
</template>
<script>
import {reject} from '@/utils/object';
export default {
inheritAttrs: false,
computed: {
otherSlots() {
return reject(this.$scopedSlots, 'default');
},
},
data() {
return {
dialog: false,
}
},
methods: {
onClose() {
this.dialog = false;
}
},
}
</script>
Usage:
<Dialog persistent>
<template v-slot:activator="{ on, attrs }">
<v-btn
v-bind="attrs"
v-on="on"
>
My button
</v-btn>
</template>
<DialogContent />
</Dialog>
onClose
is never called.
Any idea why?
Here's a sandbox to reproduce the issue: https://codesandbox.io/s/pass-event-listener-to-slot-ktemg9
Thanks
Sooo I finally succeeded to do what I wanted:
Dialog.vue
:
<template>
<v-dialog>
<slot name="default" :onClose="onClose" />
</v-dialog>
</template>
Usage:
<template v-slot:default="{onClose}">
<DialogContent @close="onClose" />
</template>
or to have a more vuetify-like syntax:
Dialog.vue
:
<template>
<v-dialog>
<slot name="default" :on="{close: onClose}" />
</v-dialog>
</template>
Usage:
<template v-slot:default="{on}">
<DialogContent v-on="on" />
</template>
I wish those props (or events) could be forwarded without having to pass them explicitly, but unfortunately this doesn't seem to be possible. :( Otherwise vuetify would do it for its activator
slots.