I’m trying to use Vuetify’s VMenu
component and I would like that when a user clicks the button the VMenu
shows up. As far as the docs goes it says we should add a scoped slot. Doing with a normal template it works but when I switch to a render function approach it never renders the button.
I have been following the Vue’s docs and ended up with:
h(VMenu, { props: { value: isMenuOpen.value } }, [ h( "template", { scopedSlots: { activator: ({ on, attrs }) => { debugger; // it never reaches this debugger return h(VButton, { on, attrs }, 'click me'); } }, }, [] ), h(VList, [h(VListItem, [h(VListItemTitle, ["Logout"])])]), ]),
I have tried using a non-arrow function as well:
scopedSlots: { activator: function({ on, attrs }) { return h('div', 'click me'); } }
and return a simple h('div', 'click me')
in both non-arrow function and arrow function and nothing seems to work.
How can I pass the scoped slot activator
to VMenu
component?
Advertisement
Answer
Scoped slots are passed through the scopedSlots
property of createElement
‘s 2nd argument in the form of { name: props => VNode | Array<VNode> }
. In your case, scopedSlots
should have two entries: one for activator
, and another for default
:
import { VMenu, VList, VListItem, VBtn } from 'vuetify/lib' export default { render(h) { return h(VMenu, { scopedSlots: { activator: props => h(VBtn, props, 'Open'), default: () => h(VList, [ h(VListItem, 'item 1'), h(VListItem, 'item 2'), h(VListItem, 'item 3'), ]), }, }) } }
which is equivalent to this template:
<template> <v-menu> <template v-slot:activator="{ on, attrs }"> <v-btn v-bind="attrs" v-on="on">Open</v-btn> </template> <v-list> <v-list-item>item 1</v-list-item> <v-list-item>item 2</v-list-item> <v-list-item>item 3</v-list-item> </v-list> </v-menu> </template>