Syntax problem in Bootstrap Vue table with scoped slot in PUG template - vue.js

From the Bootstrap Vue table documentation it is possible to render data customized.
https://bootstrap-vue.org/docs/components/table#scoped-field-slots
The example shows the following template:
<template v-slot:cell(index)="data">
{{ data.index + 1 }}
</template>
I'm using PUG as a template language and I'm having some trouble with its syntax. I didn't find the correct way to "translate" the above example to PUG syntax.
This doesn't work because of the colon:
template(v-slot:cell(index)="data") {{ data.index + 1 }}
Also this does not seem to be correct:
template(v-slot(cell(index)="data")) {{ data.index + 1 }}
Update #1
This is my field definition:
fields: [
"index",
{
key: "name",
label: this.$t("document.name"),
sortable: true
}
]
And this is the template:
b-table#filesList(
v-if="list.length > 0"
:items="list"
:fields="fields"
stacked="md"
striped
responsive
)
template(v-slot:cell(index)="data") {{ data.index + 1 }}
This only shows an empty "Index" column. If I change the template to the deprected slot and slot-scope synctax it's working:
template(slot="index" slot-scope="data") {{ data.index + 1 }}

Here's the pug "translation" of the code example in the link you provided.
I haven't used pug before, but the code below looks like it's working in this codepen.
Since you need virtual fields, you need to provide a fields array to the fields prop on b-table. That includes all the fields you want to show.
b-table(small, :fields="fields", :items="items", responsive="sm")
template(v-slot:cell(index)="data") {{ data.index + 1 }}
template(v-slot:cell(name)="data")
b.text-info {{ data.value.last.toUpperCase() }},
b {{ data.value.first }}
template(v-slot:cell(nameage)="data") {{ data.item.name.first }} is {{ data.item.age }} years old
template(v-slot:cell()="data")
i {{ data.value }}
Update
The above syntax requires Bootstrap version 2.0.0 and up.
The table slot naming for 2.0.0-rc.28 (and ONLY this version). was [field], HEAD[field] and FOOT[field].
In version 2.0.0-rc.27 and below it's field, HEAD_field, FOOT_field.
If you're using a version below that, i would suggest you update if you can, to get the latest features and fixes. But if you can't, you can instead clone the github repo and generate the documentation for the version you're using. This will allow you to see what is available at the time, and avoid future confusion.

Related

How to remove slot-scope in vue2.7

I upgraded my vue application to vue2.7 and I want to remove slot-scope from my application as it is removed in vue3. So in the examples, I see this for vue2:
<ItemList>
<template slot="heading" slot-scope="slotProps">
<h1>My Heading for {{ slotProps.items.length }} items</h1>
</template>
</ItemList>
In Vue 3 it is changed to this:
<ItemList>
<template v-slot:heading="slotProps">
<h1>My Heading for {{ slotProps.items.length }} items</h1>
</template>
</ItemList>
So in my application slot-scope is used in default:
<template slot-scope="scope">
...
</template>
So how can I remove slot-scope from my application and also for vue2.7, will it be supported?
slot-scope was deprecated in Vue2 and will never return back (even in Vue3), the syntax has just changed.
So rather than writing this: slot-scope="slotProps" you need to have the following #default="slotProps".
All the details are available here: https://v2.vuejs.org/v2/guide/components-slots.html#Scoped-Slots-with-the-slot-scope-Attribute
# being a shorthand for v-slot as explained here: https://v2.vuejs.org/v2/guide/components-slots.html#Named-Slots-Shorthand

Using vue 3 vue-i18n build-in modifiers in code/template

Vue 3s' i18n plugin has build-in modifiers for (linked) messages.
message: {
edit: 'edit',
editDesc: '#. capitalize:edit description'
}
which works fine, but the problem is I couldn't find a way to use those modifiers from within a template.
For example if I want an edit button with an capitalized 'e': <button>Edit</button>
<button>
{{ $t("edit") }}
</button>
i tried several things:
<button>
{{ $t("edit.capitalize") }}
</button>
<button>
{{ $t("capitalize.edit") }}
</button>
<button>
{{ $t(":capitalize.edit") }}
</button>
but none of these worked.
Is it even possible to use those modifiers in a template/from code, or to I have to use plain js for it.
If it is possible, how?
The modifiers can only used in i18n config messages, I suggest to define the message with capitalized format and lower it when it used in the middle/end of sentence :
message: {
edit: 'Edit',
editDesc: '#:message.edit description',
editApprove: 'Please approve the #.lower:message.edit'
}
I found it easiest to modify this in the template using plain JavaScript String methods. It has been more useful in my experience to store the message strings capitalized, then use the toLowerCase method.
<button>
{{ $t("edit").toLocaleLowerCase() }}
</button>
I have the same issue. As a workaround I use temporary linked message:
message: {
tmp: 'Actual text',
content: "#.lower:tmp"
}
And then in the template:
<p>{{ $t('message.content') }}</p>
It's ugly tho...

How to create a dynamic anchor link in nuxt.js?

I'm building a nuxt onepager that is feeded with content from the Wordpress Rest Api.
I'm already getting the Wordpress menu structure and every menu item is stored in {{ item.title }}. To scroll later to the requested div with it's id {{ item.title }} i want to complete the {{ item.title }} with a #.
My idea so far is:
<nuxt-link to="'#'{item.title}'" exact class="nav-link">{{ item.title }}</nuxt-link>
You could bind it as follows :
<nuxt-link :to="'#'+item.title" exact class="nav-link">{{ item.title }}</nuxt-link>

How to get data from single file component to display differently across my application

I am new to vuejs so please bear with me!
I have made a simple component where i pass data to it from my application, but i want to be able to play with the HTML when i reuse the component throughout my app. I have simplified everything down to make things easier, here is my .vue file:
<template>
<div>
<slot :data="data">This is a placeholder ({{data}})</slot>
</div>
</template>
<script>
export default {
name: 'test',
props: {
data: {}
}
}
</script>
And in my php file i have entered the following:
<test :data = "'testData'">
<template slot-scope="prop">
{{ prop.data }}
</template>
</test>
The problem is that when it renders it just displays {{ prop.data }} on my page and if i remove {{ prop.data }} it renders: This is a placeholder (testData).
What am i doing wrong! Or is it not possible to do what i am doing without creating another .vue file that uses the reusable component i have created?
by putting {{ prop.data }} between
<template slot-scope="prop">{{ prop.data }}</template>
Vue replace the slot in test.vue file by {{ prop.data }} and when you remove {{ prop.data }} from template you are saying render the slot content which is This is a placeholder ({{data}})

vue.js conditional rendering of an attribute [duplicate]

This question already has answers here:
VueJS conditionally add an attribute for an element
(11 answers)
Closed 4 years ago.
I'd like to learn what is the best way to conditionally render an HTML attribute in Vue.js. For example, add data-toggle="tooltip" if there is a tooltip message for current instance.
The code I have now:
<span
:data-toggle="!!col.col_spec.tooltip ? 'tooltip' : ''"
:title="col.col_spec.tooltip"
>
{{ col.col_spec.title }}
</span>
Though, I don't like the 2nd line much… Even if I use computed property here, I'd prefer not to have data-toggle attribute at all, when there is no tooltip to display.
Very so elegant solution:
<span
:data-toggle="!!col.col_spec.tooltip ? 'tooltip' : false"
:title="col.col_spec.tooltip"
>
{{ col.col_spec.title }}
</span>
Yes, yes, yes, it's just necessary that there is not an empty string, but a Boolean false
Something like:
<span ref="column">
{{ col.col_spec.title }}
</span>
And in Vue:
mounted(){
if (this.col.col_spec.tooltip){
this.$refs.column.setAttribute("data-toggle", this.col.col_spec.tooltip);
}
}
A bit late, but here is my take on it:
HTML:
<span
:data-toggle="tooltip"
:data-original-title="tooltipTitle"
>
{{ tooltipTitle }}
</span>
Vue:
methods: {
tooltipTitle: function() {
var title = this.col.col_spec.title;
if (!!title) return title;
return false;
}
}
This will remove the "data-original-title" attribute if there is none to display, consequently removing the tooltip altogether. You must use "data-original-title" instead of just "title" because Bootstrap will automatically add it once you initialise the "title" attribute, and changing "title" to false will not remove the "data-original-title".
Here's another working but not so elegant solution:
<span v-if="!!col.col_spec.tooltip" data-toggle="tooltip" >
{{ col.col_spec.title }}
</span>
<span v-else >
{{ col.col_spec.title }}
</span>