Get Vue warning when using custom SFC component in MenuButton as prop
See original GitHub issueWhat package within Headless UI are you using?
What version of that package are you using?
1.7.2
What browser are you using?
Chrome
Reproduction URL
n/a, I can create one in a codesandbox soon.
Describe your issue
I am using the dropdown menu component from HeadlessUI.
I have a custom button component (see below) that uses the <component>
utility in Vue to switch between a link, button or span depending on whether it has href prop, click event or disabled prop.
Btn.vue
<template>
<component
:is="
isDisabled && ($attrs.to || $attrs.href)
? 'span' : $attrs.to
? 'RouterLink' : $attrs.href
? 'a' : 'button'
"
>
<slot />
</component>
</template>
I want to use this <Btn>
in the :as
prop on the <MenuButton>
component.
<Menu v-slot="slotProps" as="div" class="relative">
<MenuButton
:as="Btn"
:variant="buttonVariant"
:size="buttonSize"
>
<slot name="icon" v-bind="slotProps">
<EllipsisVerticalIcon class="h-6 w-6" />
</slot>
</MenuButton>
However, I get the following warning
[Vue warn]: Non-function value encountered for default slot. Prefer function slots for better performance.
at <Btn disabled=false ref=Ref< Proxy > id="headlessui-menu-button-51" ... >
at <MenuButton as= Object variant="primary" size="md" ... >
at <Menu as="div" class="relative" >
at <DropdownMenu menu-class="right-0" >
at <AutoScroll class="grow p-5" >
at <Edit id="94d20d55-e295-4781-af66-24fb5bf11f4b" onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< Proxy > ... >
at <RouterView>
at <App>
Issue Analytics
- State:
- Created a year ago
- Comments:6 (2 by maintainers)
Top Results From Across the Web
How to reuse a SFC Vue component instance in different ...
There are two ways to do this-. Globally import the component in the main.js file and use on any page freely. i.e.-. import...
Read more >Props | Vue.js
Components can specify requirements for their props, such as the types you've already seen. If a requirement is not met, Vue will warn...
Read more >Menu (Dropdown) - Headless UI
Each component exposes information about its current state via slot props that you can use to conditionally apply different styles or render different...
Read more >Menu component - Vuetify
Vuetify is a Material Design component framework for Vue.js. ... placed absolutely on top of the activator element using the absolute prop.
Read more >Vue.js 3 Component Events Tutorial - KoderHQ
How to listen for emitted events on a parent component; How to send data with an event; How to validate an emitted event;...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
This was an issue on our part. Basically, we call the default slot ourselves to get the children vnodes and pass that to the createVNode function (usually called
h
). However, for components, they expect children in many cases to be an object w/ slot functions. Good news is we can do this even for element VNodes. I confirmed this because this is what<component>
essentially ends up compiling to + doing when passing a type ofdiv
for instance.Thanks for the report! This was merged in #1915 and will be available in our insiders build in a few minutes:
npm install @headlessui/vue@insiders
I went ahead and created a repro for this — will take a look in the am: https://sfc.vuejs.org/#eNqVU01rGzEQ/SuDKHECtkTpobDYaZJ7oeDS015kr2wr3ZWEpN3SOv7vnZH2yykN5GKvZt680Ty9ObNH53jXKlawdVSNq2VU96UBWFe6Sx/4+VWZFrpVqG3clIz+vnnrQslABgwgEj/3tQx08go5dKdK1pf3BE9tjNYMIYAi1T5FU7JZsJNeS0Ntdgn/I5+vMEH/USNgi4cpO7bEpnRPMLIhrN5ja4Yz7LSprmeYlQCczzCm4HKZsQmKTxOJaaRBpRTK2oks3lrMJMVj2HvtIgQVW4cR3TjrI5yBCpfpNzPCBQ7eNlCyh5OSVa1CaLXAV6JB+yoUbgBxgQd6xKxDaWoV4Uo+2CDsYC0BpiRJN8/gjOmC92zJcpdVIx1/DtagPc6Ju0+gbgWkCMVS6wI/TjG6UAgRDnu6z3Pg1h/p4ty3JupGcRWa1c7bX0F5JC7ZcsYhMNgpv/LKVMor/xbnK+j/ef9RcM7ZGvfzyPe2Ea9gDx/5Z/4JnzFEMWWoS2IncjTHBYXqpX9rf7LagG2cNcrEojfMzpMtYhkrdZBtjcZAixWjCQPv4zzabfTaHG/vkiepJBcnmpEXCk0rNZ6//3ZXW5gWQox2HXHv8ezMtW1QjzH6sAS8pzYqLc2Swlu6/WTi3pnZeh8k1aDthvLbu5xwaec2c7IhldTIJYma4jlzNSsiMjvHd5O7WlVwcwO3fSxaeHkZACevDkgC8AUWwUmzIFWLIRstHVMSRUm5WZZq0y5gEBGyzxNikZ96gTs4LdPlL4hp0Nc=