I created functionality for the collapse where inside the body table, and there is the "+" add button, when I click on it it adds new collapse(another) with content and the I want to display the name of data row for example "Iphone" and appears new collapse with "Iphone" title/name.
It works great but I have issue, when I add, the title of created collapse is: "object MouseEvent"
CollapseSection.vue
<template>
<div class="accordion" role="tablist">
<b-button block v-b-toggle.accordion-1 class="collapse-btn" align-h="between">
{{ selectText }}
<b-icon :icon="visible ? 'caret-down' : 'caret-up'" class="icon"></b-icon>
</b-button>
<b-card no-body class="mb-1">
<b-collapse id="accordion-1" v-model="visible" accordion="my-accordion" role="tabpanel">
<SearchField></SearchField>
<b-card-body>
<!-- CONTENT WOULD APPEAR INSIDE THIS SLOT -->
<slot name="content" :addItem="addItem">
</slot>
</b-card-body>
</b-collapse>
</b-card>
<!-- DYNAMIC CONTENT COLLAPSE WHEN CLICK ON ADD BUTTON -->
<div v-for="(item, index) in items" :key="index">
<b-button block v-b-toggle="'accordion-' + (index + 2)" class="collapse-btn">
{{ item.name }}
<b-icon :icon="visible ? 'caret-down' : 'caret-up'" class="icon"></b-icon>
</b-button>
<b-card no-body class="mb-1">
<b-collapse :id="'accordion-' + (index + 2)" accordion="my-accordion" role="tabpanel">
<b-card-body>
<!-- CONTENT WOULD APPEAR INSIDE THIS SLOT -->
<slot name="createdContent">
</slot>
</b-card-body>
</b-collapse>
</b-card>
</div>
</div>
</template>
<script>
import SearchField from "@/components/UI/SearchField.vue";
export default {
name: "CollapseButton",
components: {SearchField},
props: {
selectText: {
type: String,
default: () => "Select",
},
},
data() {
return {
isConfiguring: false,
configuringItem: null,
items: [],
visible: false,
}
},
methods: {
addItem(name) {
const item = { name };
this.items.push(item);
this.isConfiguring = true;
this.configuringItem = item;
this.$emit('item-added', item);
}
},
}
</script>
DataTable.vue
<template>
<tbody>
<tr v-for="(item, itemIndex) in data" :key="itemIndex">
<td>
<slot></slot>
</td>
<td v-for="(label, labelIndex) in labels" :key="labelIndex">
{{ item[label.field] }}
</td>
</tr>
</tbody
</template>
<script>
export default {
name: "DataTable",
components: {ActionColumn},
props: {
labels: {
type: Array,
required: true,
},
data: {
type: Array,
required: true,
},
},
methods: {
addItem(name) {
this.$emit('add-item', name);
}
}
}
</script>
NewLab.vue
<CollapseSection select-text="Select Images">
<template #content="{ addItem }">
<DataTable :labels="labels" :data="data" :showAdd="true">
<b-icon icon="plus" class="add-btn" @click="addItem(data.name)">
</b-icon>
</DataTable>
</template>
<template #createdContent>
<CollapseTabContent>
</CollapseTabContent>
</template>
</CollapseSection>
<script>
const labels = [
{text: "Name", field: 'name'},
{text: "Description", field: 'description'},
]
const data = [
{name: 'Windows 1', description: 'Password Cracking'},
{name: 'Windows 13', description: 'SIEM and MISP machine'},
{name: 'Windows 15', description: 'AD auditing lab'},
{name: 'Windows 31', description: 'Threat Hunting and Investigation'},
];
export default {
name: "NewLab",
components: {DataTable, CollapseSection},
data() {
return {
labels: labels,
data: data,
};
},
</script>
SOLVED. I tried all possible solutions and nothing helped me. I asked GPT, different QNA forums also telegram channels with the VueJS community. I did not use any other technologies like VueX, etc. What I've done to solve the problem, First of all, I separated the Dynamic content of Collapse into a separate component DynamicCollapse.vue
After that, I assumed not to pass the add button as a slot into DataTable
here is the method of DataTable.vue
and finally in the parent component
and inside the parent component in section pass the data and method(I will refactor it in the future)
I spent a week solving it by reading and gaining a lot of information about the slots, data, scoped slots, etc. So I think this answer would help you.