Search code examples
vue.jsvuejs3nuxt3.jsvue-script-setupvue-typescript

Unable to reference slot props inside template


I get the following warning in the browser when I try to reference the slot props. What am I missing?

[Vue warn]: Property "disabled" was accessed during render but is not defined on instance.

This is a link to a sandbox. The error is reproduced here https://codesandbox.io/p/sandbox/elated-star-7x6wd9?file=%2Fapp.vue%3A1%2C1

//Usage
<script setup lang="ts">
</script>

<template>
   <MenuItem
          :disabled="true"
          v-slot="{ disabled }"
          :class="{ 'bg-slate-400 text-white': disabled }"
        >
        Item 1
        </MenuItem>
</template>

And this is the implementation of the MenuItem component.

<script setup lang="ts">
import type { Component } from 'vue'

export interface MenuListItemProps {
  as?: string | Component
  disabled?: boolean
}
export interface MenuListItemSlots {
  default(props: { disabled: boolean }): any
}

withDefaults(defineProps<MenuListItemProps>(), {
  as: 'li',
  disabled: false
})

defineSlots<MenuListItemSlots>()



const itemref = ref<HTMLElement | null>()


</script>

<template>
  <component
    :is="as"
    role="menuitem"
    tabindex=-1
    ref="itemref"
    :disabled="disabled"
  >
    <slot
      name="default"
      :disabled="disabled" //slot prop is being provided here
    />
  </component>
</template>

I was expecting the disbaled slot prop to be accessible on the class binding. However when i try to access that as shown in the code. I do get a warning.


Solution

  • While I don't understand why the usage above won't work. I figured a way around it.

    <MenuItem
          :disabled="true"
          v-slot="{ disabled }"
        >
        <span :class="{ 'bg-slate-500 text-white': disabled, 'block': true }">
          Item 3
        </span>
    </MenuItem>
    

    I'm thinking perhaps you can't use slot props on the component providing those props. You can only use the slot props on elements or components inside the slot content.