Vue и Bootstrap Vue - динамически использовать слоты

Я пытаюсь сделать в таблице bootstrap-vue слот для отображения любого логического значения с помощью настраиваемого компонента.

Итак, у меня есть простая таблица

<b-table :items="items" :fields="columns" >

</b-table>

Теперь, если я хочу отрендерить отдельный столбец определенным образом, мне нужно использовать слот

<template v-slot:cell(active)="data" >
    <my-component :item="data.item" />
</template>

И это работает, потому что я знаю, что active является логическим.

Я хотел бы обобщить это поведение, но я не могу использовать v-for в шаблонах и не может использовать v-slot:cell(active) если не в шаблоне... Идея заключалась в том, чтобы создать массив со всеми моими логическими полями и перебирать его... но это не работает..

Что-то вроде этого

<template v-slot:cell(b)="data" v-for="b in booleanFields">
    <my-component :item="data.item[b]" />
</template>

1 ответ

Решение

Поскольку Vue поддерживает динамические имена слотов, вы можете использовать переменные для установки имен слотов с помощью v-bind:[attributeName]="value" синтаксис.

Таким образом вы могли бы сделать что-то вроде:

<template v-slot:['cell(' + b + ')']="data" v-for="b in booleanFields">

Но использование кавычек там невозможно из-за ограничений выражения динамического аргумента. Поэтому вам нужно создать вспомогательный метод для этой конкатенации. Так:

<template v-slot:[gomycell(b)]="data" v-for="b in booleanFields">

плюс

methods: {
  gomycell(key) {
    return `cell(${key})`; // simple string interpolation
  }

Естественно, вы могли бы просто назвать метод gomycell как cell и используйте это как v-slot:[cell(b)]="data" (обратите внимание на []s), но я оставил имя gomycell именно поэтому в этом текстовом примере яснее, какое имя у метода, а что нет.


Демо:

Вот небольшая демонстрация, демонстрирующая использование динамических имен слотов, это неb-table но я думаю, что это достаточно хорошо, чтобы показать, что это возможно:

Vue.component('my-table', {
  template: '#my-table',
})

new Vue({
  el: '#app',
  data: {
    booleanFields: [true, false]
  },
  methods: {
    gomycell(key) {
      return `cell(${key})`;
    }
  }
})
<script src="https://unpkg.com/vue"></script>

<div id="app">
  <my-table>
    <template v-slot:[gomycell(b)]="data" v-for="b in booleanFields">
      <h3>who? {{ data.is }}</h3>
    </template>
  </my-table>
</div>

<template id="my-table">
  <div>
    <div style="color:green"><slot name="cell(true)" v-bind="{is: 'true!'}"></slot></div>
    <div style="color:red"><slot name="cell(false)" v-bind="{is: 'false!'}"></slot></div>
  </div>
</template>

Другие вопросы по тегам