If I'm understanding correctly, you want to be able to have a slot to customize the layout when the field is not being editted.
For this you will have to create your own component, wrapping <b-table>
, and create your own slot.
<template v-slot:cell()="data">
<b-input
v-if="data.item.editing && data.field.editable"
v-model="tableData[data.index][data.field.key]"
/>
<span v-else>
<slot :name="`noedit(${data.field.key})`" v-bind="data">
{{ data.value }}
</slot>
</span>
</template>
The above code, will then allow you to use the slot noedit(field_key)
(you can change the slot name to whatever you want), to edit the layout when that field is not in an "editing" state.
Example
Vue.component("data-table", {
template: "#data-table",
computed: {
editableFields() {
return this.fields.filter((field) => field.editable);
}
},
data() {
return {
userRow: null
};
},
props: ["items", "fields"],
methods: {
editUser(user) {
let doEdit = true;
if (
this.userRow &&
!confirm("You have unsaved changes, are you sure you want to continue?")
) {
doEdit = false;
}
if (doEdit) {
this.userRow = { ...user };
}
},
saveEdit() {
let user = this.items.find((u) => u.id === this.userRow.id);
Object.assign(user, this.userRow);
this.resetEdit();
},
resetEdit() {
this.userRow = null;
}
}
});
new Vue({
el: "#app",
data() {
return {
fields: [
{ key: "id" },
{ key: "first_name", editable: true },
{ key: "last_name", editable: true },
{ key: "age", editable: true, type: "number", isNumber: true },
{ key: "actions" }
],
items: [
{ id: 1, first_name: "Mikkel", last_name: "Hansen", age: 56 },
{ id: 2, first_name: "Mads", last_name: "Mikkelsen", age: 39 },
{ id: 3, first_name: "Anders", last_name: "Matthesen", age: 42 }
]
};
}
});
<link href="https://unpkg.com/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://unpkg.com/[email protected]/dist/bootstrap-vue.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.js"></script>
<script src="https://unpkg.com/[email protected]/dist/bootstrap-vue.js"></script>
<div id="app">
<data-table :items="items" :fields="fields">
<template v-slot:noedit(first_name)="{ value }">
<b class="text-primary">
{{ value }}
</b>
</template>
<template v-slot:cell(id)="{ value }">
<i class="text-danger">{{ value }}</i>
</template>
</data-table>
</div>
<template id="data-table">
<b-table :items="items" :fields="fields">
<template v-for="field in editableFields" v-slot:[`cell(${field.key})`]="s">
<b-input v-if="userRow && userRow.id === s.item.id" v-model="userRow[s.field.key]" :type="s.field.type || 'text'" :number="s.field.isNumber">
</b-input>
<template v-else>
<slot :name="`noedit(${s.field.key})`" v-bind="s">
{{ s.value }}
</slot>
</template>
</template>
<template v-slot:cell(actions)="{ item }">
<b-button-group v-if="userRow && userRow.id === item.id">
<b-btn variant="success" @click="saveEdit">
Save
</b-btn>
<b-btn variant="danger" @click="resetEdit">
Cancel
</b-btn>
</b-button-group>
<b-btn v-else variant="primary" @click="editUser(item)">
Edit
</b-btn>
</template>
<!-- Pass in slots from parent -->
<template v-for="name in Object.keys($scopedSlots)" v-slot:[name]="scope">
<slot :name="name" v-bind="scope"></slot>
</template>
</b-table>
</template>