Using generic value in v-slot:head - vue.js

I try to create a generic Bootstrap Vue Table Component. For the field label in HTML format, I try to do something such:
<template v-for="field in fields" v-slot:head(field_name)>
<span v-translate render-html="true" v-html="field.label"></span>
</template>
Here, my problem is, when I put v-slot:head(field_name), the field_name is not generic and it is accepting as a string. So when I write field.key to v-slot:head, I want it to check the value of field.key but not field.key as the value itself.
<template v-for="field in fields" v-slot:head(field.key)>
<span v-translate render-html="true" v-html="field.label"></span>
</template>
Is there any way to handle this?

The syntax for dynamic slots is:
<template v-slot:[dynamicSlotName]>
// ...
</template>
Applied to your case:
<template v-for="field in fields" v-slot:[`head(${field.key})`]>
<span v-translate render-html="true" v-html="field.label"></span>
</template>

Related

How do I retrieve the value of my key button and row in v-for using Vue.js?

I am new to Vue.js and I trying to learn now to use it. I have 3X3 structure of buttons
I have the following sample code:
<template v-for="row in 3">
<div class="row" :key="row">
<button #click="nextPlayer(button, row)" v-for="button in 3" :key="indexByrow(button, row)" :value="squares[indexByrow(button, row)]" class="square" style="width:40px;height:40px;"></button>
</div>
</template>
When I click, I want to pass the button and row to nextPlayer(button, row), and the indexByrow(button, row) to use those values in the methods, but I don't seem to have any values. My main goal is to change the value name when I click on it.
You need to make the below changes
<template v-for="(row, indx) in 3">
<div class="row" :key="indx">
<button #click="nextPlayer(button, row)" v-for="(button, indexer) in 3" :key="indexer" :value="squares[indexByrow(button, row)]" class="square" style="width:40px;height:40px;"></button>
</div>
</template>
Not sure if indexByrow is a computed property or method.
You need to modify the logic in indexByrow as well based on the above changes

Vuetify data table - manually display expandable rows

I have a bunch of dynamic columns in a v-data table which I need to loop through and interrogate in order to display the correct info. It looks a bit like this (taken from the answer here: Vuetify format cell based on item type)
<v-data-table :item="items" ... >
<template v-for="header in headers" v-slot:[`item.${header.value}`]="{ item } ">
<template v-if="header.type === 'foo'">
<span style="color: red;">{{ item[header.value] }}</span>
</template>
<template v-else-if="header.value === 'data-table-expand'">
???
</template>
<template v-else>
{{ item[header.value] }}
</template>
</template>
</v-data-table>
Since I need the v-if statement, all other types default to the v-else. However, the v-else is not suitable for when a type is an expandable row. It will display a blank value for that column. So I created a v-else-if template to be able to capture the expandable row column and correctly render it to the screen.
The problem is that I don't know what to put in the template to indicate it's a column with expandable rows (https://vuetifyjs.com/en/components/data-tables/#expandable-rows). In other words it does not render the carat icon that shrinks/expands the subtable, nor does it render the clickable actions. How would I modify the v-else-if template to correctly render its contents?
I came up with a workaround using computed properties.
Instead of using
v-for="header in headers"
I changed it to a computed headers which is filtered.
<template v-for="header in headersIWant" v-slot:[`item.${header.value}`]="{ item } ">
<span style="color: red;">{{ item[header.value] }}</span>
</template>
...
computed: {
headersIWant() {
return this.headers.filter(x => x.type === 'foo');
}
}

How to show value dynamically in vue js wth div

showing values from url dynamically, already showing in table correctly, but i want show with div.
<vs-table ref="table" multiple v-model="selected" pagination :max-items="itemsPerPage" :data="products">
<template slot-scope="{data}">
<vs-tr :data="row" :key="index" v-for="(row, index) in data">
<vs-td>
<p>{{data[index].name}}</p>
</vs-td>
</vs-tr>
</template>
</vs-table>
now checking with this div
<template slot-scope="{data}">
<div v-for="(row1, index1) in data" v-bind:key="row1.id">
{{data[index1].name}}
</div>
</template>
this div code not working
If you are running these both on the same page it might have something to do with your :keys being on the same ID. e.g. set the keys with a prefix
<div v-for="(row, index) in data" v-bind:key="'div-'+row.id">
{{data[index].name}}
</div>

Vue.js / Algolia - Dynamically pass field names in template

I am trying to dynamically show search results from Algolia, based on an array of names.
Input.vue:
<search-results title="Books" :fields="['booking_reference','shipment_reference']"></search-results>
Results.vue:
<template slot-scope="{ result }">
<h1 v-for="field in fields">{{ result.field }}</h1>
</template>
However, above code does not return anything in my template. It's just blank.
But my fields array does indeed have values:
And I can see the results from Algolia as well:
But it does not show the results.
If I edit the code and hardcode the field name I want to show, like this:
<template slot-scope="{ result }">
{{ result.booking_reference }}
</template>
I can see the result just fine in my template.
What am I doing wrong?
Update:
How can I do this with a multidimensional array?
My array:
fields:Array[2]
0:Object
maintitle:"booking_reference"
1:Object
subtitle:"shipment_reference"
I need to be able to access it like:
result.maintitle.field
try
<h1 v-for="field in fields">{{ result[field] }}</h1>
instead of
<h1 v-for="field in fields">{{ result.field }}</h1>

Not binding the IF to any element in Vue

This works:
<span v-if="name">
Hi there, {{ name }}
</span>
... but it forces me to use span for the whole text, I just want it on the name variable. In handlebars for example I could do:
{{#if name}}
Hi there, <span>{{ name }}</span>
{{/if}}
You can use a template for that.
we can use v-if on a <template> element, which serves as an invisible
wrapper. The final rendered result will not include the <template>
element.
For example:
<template v-if="name">
Hi there, <span>{{ name }}</span>
</template>