Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue and Bootstrap Vue - dynamically use slots

I'm trying to make in a bootstrap-vue table a slot to render any boolean value with a custom component.

So I have a simple table

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

</b-table>

Now if i want to render a single column in a particular way i have to use a slot

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

And it works, because I know that active is a boolean.

I would like to generalize this behavior but i cannot use v-for in templates and cannot use v-slot:cell(active) if not on template... The idea was to create an array with all my boolean fields and iterate on it... but it does not work..

Something like this

<template v-slot:cell(b)="data" v-for="b in booleanFields">
    <my-component :item="data.item[b]" />
</template>
like image 536
MarioC Avatar asked Sep 27 '19 20:09

MarioC


People also ask

Can you use Bootstrap and Vue together?

Bootstrap-Vue not only supports the Bootstrap components and grid system, but also includes support for Vue. js Directives, which gives us the full feature set from the Vue. js ecosystem. One of the cool features of Bootstrap-Vue is that it has an online Playground.

How do I use Vue JS slots?

How to use it. 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.

Is Vue better than Bootstrap?

"Responsiveness", "UI components" and "Consistent" are the key factors why developers consider Bootstrap; whereas "Simple and easy to start with", "Good documentation" and "Components" are the primary reasons why Vue. js is favored.

Why use Vue JS slots?

Slot props allow us to turn slots into reusable templates that can render different content based on input props. This is most useful when you are designing a reusable component that encapsulates data logic while allowing the consuming parent component to customize part of its layout.


1 Answers

Because Vue supports Dynamic Slot Names, you can use variables to set the slot names using the v-bind:[attributeName]="value" syntax.

This way you could do something like:

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

But using the quotes there is not possible due to the dynamic argument expression constraints. So you'll have to create a helper method to do that concatenation. So:

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

plus

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

Naturally, you could just name the method gomycell as cell and use it like v-slot:[cell(b)]="data" (notice the []s), but I left the name gomycell just so in this texample it is clearer what is the name of the method and what is not.


Demo:

Here's a small demo showcasing the dynamic slot names usage, it's not b-table but I think it is good enough to show it is possible:

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>
like image 63
acdcjunior Avatar answered Oct 21 '22 19:10

acdcjunior