Как передать шаблоны ячеек в компонент с b-таблицей?
Я создал компонент, который показывает данные таблиц для разных страниц. Этот компонент использует внутри b-таблицу. Теперь для пары страниц я хочу настроить рендеринг некоторых столбцов, а таблицы Bootstrap позволяют использовать слоты полей с ограниченной областью действия со специальным синтаксисом:
<template #cell(field)="data">
{{ data.item.value }}
</template>
где field - имя столбца, полученное из моего массива со столбцами, а data.item - элемент ячейки, который нужно отобразить.
Проблема в том, что у меня разные поля для разных страниц, поэтому эта настройка должна исходить из родительского компонента, и эти шаблоны должны создаваться динамически.
Вот как я пытался это решить:
Передайте через свойство MyTableComponent массив с настраиваемыми полями и уникальными именами слотов. В MyTableComponent динамически создавайте шаблоны для настройки, а внутри динамически создавайте именованные слоты.
От данных родительского слота к именованным слотам
MyTableComponent:
<b-table>
<template v-for="slot in myslots" v-bind="cellAttributes(slot)">
<slot :name="slot.name"></slot>
</template>
</b-table>
<script>
...
computed: {
cellAttributes(slot) {
return ['#cell(' + slot.field + ')="data"'];
}
}
...
</script>
Родитель:
<MyTableComponent :myslots="myslots" :items="items" :fields="fields">
<template slot="customSlot1">
Hello1
</template>
<template slot="customSlot1">
Hello2
</template>
</MyTableComponent>
<script>
...
items: [...my items...],
fields: [...my columns...],
myslots: [
{ field: "field1", name: "customSlot1" },
{ field: "field2", name: "customSlot2" }
]
...
</script>
К сожалению, компонент b-table просто игнорирует мои пользовательские слоты, как если бы они не были предоставлены. Он работает, если я укажу в MyTableComponent напрямую:
<b-table>
<template #cell(field1)="data">
{{ data.item.value }}
</template>
</b-table>
Но мне нужно, чтобы это выполнялось динамически через свойства компонента. Пожалуйста помоги.
1 ответ
Вы можете использовать функцию динамических имен слотов в Vue 2, чтобы передать все (или некоторые) слоты от родителя к
<b-table>
внутри ребенка вот так:
Ребенок:
<b-table>
<template v-for="(_, slotName) of $scopedSlots" v-slot:[slotName]="scope">
<slot :name="slotName" v-bind="scope"/>
</template>
</b-table>
$scopedSlots содержит все слоты, переданные вашему компоненту. Вы можете отфильтровать его, если хотите (у вас есть слот, специфичный для вашего компонента-оболочки, который вы не хотите передавать
<b-table>
) путем создания
computed
Теперь это будет работать:
<MyTableComponent :items="items" :fields="fields">
<template #cell(field1)="data">
{{ data.item.value }}
</template>
</ MyTableComponent>