Как передать шаблоны ячеек в компонент с 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>
Другие вопросы по тегам