Search code examples
vue.jscomponents

Vue - detect component inside slot


I have this slot inside my tile component. I basically need to detect a specific other component which is supposed to be used inside this slot BUT the slot also supports other html tags not just this specific component. Is there a way to detect a special component e.g. <listitem /> inside the slot?

<div class="tile">
  <template v-if="$slots['headline']">
    <slot name="headline" />
  </template>
</div>

Edit The basic idea is the following

<tile>
  <template #headline>
    <listitem />
  </template>
</tile>

<tile>
  <template #headline>
    <h1>Some headline</h1>
  </template>
</tile>

I have those two options on how you can utelise this header slot. If there is a just a normal html tag e.g. <h1>, I would like to apply the corresponding css styles. If there is the <listitem /> component I need to apply other styles


Solution

  • As content of the slot is passed to the component as an array of VNode's accessible via this.$slots (in case of scoped-slots it is function returning array of VNode's) you can write a function like this:

    methods: {
        isListitem() {
            return this.$slots.headline && this.$slots.headline[0].tag.endsWith('-listitem')
        }
      }
    

    Main problem is that $slots is not reactive

    Docs: Please note that slots are not reactive. If you need a component to re-render based on changes to data passed to a slot, we suggest considering a different strategy that relies on a reactive instance option, such as props or data

    So I don't recommend doing this and follow the Vue documentation suggestion to use props instead...