Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue - how to pass down slots inside wrapper component?

So I've created a simple wrapper component with template like:

<wrapper>    <b-table v-bind="$attrs" v-on="$listeners"></b-table> </wrapper> 

using $attrs and $listeners to pass down props and events.
Works fine, but how can the wrapper proxy the <b-table> named slots to the child?

like image 533
user3599803 Avatar asked Jun 16 '18 21:06

user3599803


People also ask

How do I pass variables between components Vue?

Using Props To Share Data From Parent To Child # VueJS props are the simplest way to share data between components. Props are custom attributes that we can give to a component. Then, in our template, we can give those attributes values and — BAM — we're passing data from a parent to a child component!

How do you pass Props to Vue component?

To specify the type of prop you want to use in Vue, you will use an object instead of an array. You'll use the name of the property as the key of each property, and the type as the value. If the type of the data passed does not match the prop type, Vue sends an alert (in development mode) in the console with a warning.

How do I use Vue JS slots?

Using the slot is very easy, we should just write the <slot> component (which is a reserved word in Vue. js) inside the child component's template, where we want to receive data. A child component uses slot.


1 Answers

Vue 3

Same as the Vue 2.6 example below except:

  • $listeners has been merged into $attrs so v-on="$listeners" is no longer necessary. See the migration guide.
  • $scopedSlots is now just $slots. See migration guide.

Vue 2.6 (v-slot syntax)

All ordinary slots will be added to scoped slots, so you only need to do this:

<wrapper>   <b-table v-bind="$attrs" v-on="$listeners">     <template v-for="(_, slot) of $scopedSlots" v-slot:[slot]="scope"><slot :name="slot" v-bind="scope"/></template>   </b-table> </wrapper> 

Vue 2.5

See Paul's answer.


Original answer

You need to specify the slots like this:

<wrapper>   <b-table v-bind="$attrs" v-on="$listeners">     <!-- Pass on the default slot -->     <slot/>      <!-- Pass on any named slots -->     <slot name="foo" slot="foo"/>     <slot name="bar" slot="bar"/>      <!-- Pass on any scoped slots -->     <template slot="baz" slot-scope="scope"><slot name="baz" v-bind="scope"/></template>   </b-table> </wrapper> 

Render function

render(h) {   const children = Object.keys(this.$slots).map(slot => h('template', { slot }, this.$slots[slot]))   return h('wrapper', [     h('b-table', {       attrs: this.$attrs,       on: this.$listeners,       scopedSlots: this.$scopedSlots,     }, children)   ]) } 

You probably also want to set inheritAttrs to false on the component.

like image 146
Decade Moon Avatar answered Oct 06 '22 08:10

Decade Moon