Reputation: 914
I have a component called "List" which contains a vue boostrap table:
<template>
<div>
<b-table :items="items">
<!--<template slot="createdAt" slot-scope="row"> usually vue boostrap table row templates live here-->
<!--{{row.item.createdAt|dateFormatter}}-->
<!--</template>-->
<slot name="tableTemplates"></slot> <!-- but i want to pass the templates from my parent template -->
</b-table>
</div>
</template>
I'm passing the table items from my parent Component "Orders". I also want to pass row templates to the vue boostrap b-table component.
Unfortunately i can't get it to work using slots (That would be a template inside a template)
<template>
<div>
<list :items="items">
<template slot="tableTemplates">
<!--templates inside templates do not work-->
<template slot="id" slot-scope="row">
<span v-b-tooltip.hover :title="row.item.id">{{row.item.id|uuidFormatter}}</span>
</template>
<template slot="createdAt" slot-scope="row">
{{row.item.createdAt|dateFormatter}}
</template>
<template slot="customer" slot-scope="row">
{{row.item.customer}}
</template>
</template>
</list>
</div>
</template>
Upvotes: 3
Views: 4675
Reputation: 5186
You can just change IVO's answer and make your List component generic.
Here is one possible way to do that:
List component template:
<template>
<b-table striped hover :items="items">
<template :slot="slot.field" slot-scope="row" v-for="slot in slots">
<slot :name="slot.name" :tbl="row"></slot>
</template>
</b-table>
</template>
List component props:
props: {
items: {
type: Array
},
slots: {
type: Array
}
},
Then, in any parent components (using List), you can define a templates
data property, with an array of template instructions to be passed to the List component. In the example, I used an array of objects to pass the dynamic slot name and table data field.
Parent component templates
data property:
data() {
return {
...
templates: [
{
name: "templateName",
field: "dataFieldName"
},
...
]
};
},
Parent component template, List usage:
<list :items="items" :slots="templates">
<template slot="customSlotName" slot-scope="data">
// Custom template here...
</template>
</list>
This will keep all your custom template logic living in the parent component, ex. Order.vue, and not in List.vue.
Here is the updated codesandbox: https://codesandbox.io/s/244p9rx10n
Upvotes: 9
Reputation: 14269
Have you tried like that ? You get the scope from the table's slot and then provide this scope inside your nested slot:
<template>
<div>
<b-table :items="items">
<template slot-scope="row">
<slot name="tableTemplates" :tbl-props="row"></slot>
</template>
</b-table>
</div>
</template>
Upvotes: 4