Home > Net >  Vue slot not working - child elements show as empty array
Vue slot not working - child elements show as empty array

Time:10-05

I have the following code where I am trying to pass individual tab components into a tabs component via slots. However, the tabs do not seem to be getting passed. Putting {{ tabs }} on the template only shows an empty array.

<template>
  <article>
    {{ tabs }} // empty array
    <header >
      <ul>
        <li v-for="(tab, index) in tabs" :key="index">
          <div 
              :
              @click="selectTab(tab)">
            {{ tab.name }}
          </div>
        </li>
      </ul>
    </header>
    <section >
      <slot></slot>
    </section>
  </article>
</template>

<script>
  export default {
    data: () => {
      return {
        tabs: []
      }
    },
    methods: {
      selectTab(selectedTab) {
        this.tabs.forEach(tab => {
          tab.isActive = tab.name === selectedTab.name;
        });
      }
    },
    created() {
      console.log('created[Tabs.vue]-> ',  this.$children) // nothing here
      this.tabs = this.$children; // not working
    }
  }
</script>

I have my components registered in the parent like so:

 import Tab from '@/components/Tab'
 import Tabs from '@/components/Tabs'

  export default {
    components: {
      Datepicker,
      Tab,
      Tabs
    },
...

The template is pretty straight forward. Note, the contents of the individual tabs display fine when selected="true"

  <Tabs>
    <Tab name="hours" selected="true">Contents here...</Tab> 
    <Tab name="pay"></Tab>
  </Tabs>

I have checked in the browser console and, although the nav-item <li> elements are being created, they have no content.

I'm new to slots so maybe I am missing something obvious or the code syntax I am using is outdated. Any help is much appreciated.

CodePudding user response:

Try to use this.$slots :

this.tabs = this.$slots.default();//returns vnodes, that can be rendered via render function

CodePudding user response:

$children has been deprecated in Vue 3:

In 3.x, the $children property is removed and no longer supported. Instead, if you need to access a child component instance, we recommend using template refs.


If you're trying to get children of <slot></slot>, use this.$slots.default(), as suggested in Boussadjra's answer.

  • Related