how to get target of vue draggable - vue.js

I am using vue draggable element like this
<b-row v-for="(stage,index) in Pdata" :key="index">
<!-- people group 1 -->
<b-col md="6">
<h6 class="text-primary font-weight-bold mb-2">
{{stage.stage}}
</h6>
<!-- draggable -->
<draggable
:list="stage.items"
group="people"
class="list-group list-group-flush cursor-move"
>
<b-list-group-item
v-for="listItem in stage.items"
:key="listItem.id"
tag="li"
>
<div class="d-flex">
<b-card>
<b-card-text >
{{listItem.name}}
</b-card-text>
</b-card>
<!-- <b-avatar :text="listItem.name.slice(0,2)" />
<div class="ml-25">
<b-card-text class="mb-0 font-weight-bold">
{{ listItem.name }}
</b-card-text>
<small>{{ listItem.email }}</small>
</div> -->
</div>
</b-list-group-item>
</draggable>
</b-col>
</b-col> -->
</b-row>
here the structure of Pdata is like this
Pdata :[
{stage:'1',
id:'1'
items:[]
},
{stage:'2',
id:'2'
items:[]
}
{stage:'3',
id:'3'
items:[]
}
]
here after the vue drag operation i want to add element to the particular Stage in which the item is dragged. How can i get the particular stage id in Pdata so that data can be changed in database ?

Related

get target list after drag operation in vue -draggable

I am using vue draggable element like this
<b-row v-for="(stage,index) in Pdata" :key="index">
<!-- people group 1 -->
<b-col md="6">
<h6 class="text-primary font-weight-bold mb-2">
{{stage.stage}}
</h6>
<!-- draggable -->
<draggable
:list="stage.items"
group="people"
class="list-group list-group-flush cursor-move"
>
<b-list-group-item
v-for="listItem in stage.items"
:key="listItem.id"
tag="li"
>
<div class="d-flex">
<b-card>
<b-card-text >
{{listItem.name}}
</b-card-text>
</b-card>
<!-- <b-avatar :text="listItem.name.slice(0,2)" />
<div class="ml-25">
<b-card-text class="mb-0 font-weight-bold">
{{ listItem.name }}
</b-card-text>
<small>{{ listItem.email }}</small>
</div> -->
</div>
</b-list-group-item>
</draggable>
</b-col>
</b-col> -->
</b-row>
here the structure of Pdata is like this
Pdata :[
{stage:'1',
id:'1'
items:[]
},
{stage:'2',
id:'2'
items:[]
}
{stage:'3',
id:'3'
items:[]
}
]
here the draggable element is put on the Pdata.items which is an array of objects,
How can I trigger a function which should detect the data is dragged across the list and the target list name and id so that i can store the data in databases

how to display data from props in b-table template tag?

i am new in vue.js and get some problem while displaying data in b-table. my data from database is fetched properly. and i passed from one file to products.vue and received data in products.vue as props. when i console my data is showing in console properly, but when i used to display data in b-table, i got some problem. data is not displaying correctly.
please let me know where is mistake in my code?
Products.vue (script tag)
<script>
export default {
props: ['category','singular', 'plural','products'],
data() {
return {
title: `All ${this.plural}`,
items: [],
editing: false,
weight_assignment: false,
model: null,
formTitle: '',
fields: [
{
key: 'index',
label: 'S.No.'
},
{
key: 'name',
sortable: true
},
{
key: 'weights'
},
{
key: 'default_weight',
sortable: true
},
{
key: 'status',
sortable: true
},
{
key: 'action'
}
],
}
</script>
Product.vue (template tag)
<template>
<div class="row">
</div>
<div class="col-12">
<div class="card">
<div class="card-header">
<h3 class="card-title">{{title}}</h3>
<div class="card-tools">
<b-button variant="primary" #click="newItem">New {{singular}}</b-button>
<div></div>
</div>
</div>
<div class="card-body table-responsive p-0">
<spinner v-if="$root.loading"></spinner>
<b-table ref="table" v-for="type in this.products" :items="type" :key="type.id" :fields="fields" bordered hover :head-variant="'light'" responsive="sm" v-else>
<template v-slot:cell(index)="type">
{{ type.index + 1 }}
</template>
<template v-slot:cell(name)="type">
<b-img thumbnail fluid :src="getImageUrl(type.image)" alt="Image 1" class="thumb-img"></b-img>
{{type.name}}
</template>
<template v-slot:cell(weights)="type">
<span v-weights="type.item"></span>
</template>
<template v-slot:cell(default_weight)="type">
<span v-floatFormatter="type.default_weight"></span>{{type.unit.sname}}
</template>
<template v-slot:cell(status)="type">
<span v-if="type.status" class="text-success text-bold">Active</span>
<span class="text-danger" v-else>Inactive</span>
</template>
<template v-slot:cell(action)="data">
<a #click.prevent="editItem(data.index)"><i class="fa fa-edit" aria-hidden="true" title="Update product" v-b-tooltip.hover></i></a>
<a #click.prevent="assignWeights(data.index)"><i class="fa fa-balance-scale" title="Assign weights" aria-hidden="true" v-b-tooltip.hover></i></a>
</template>
</b-table>
</div>
</div>
</div>
</div>
</template>
v-for="type in this.products" - try to delete this key. In template tag do not use this keyword to access data or any other values.
I have spotted you pass data completely wrong way. Please use below variant and tell me if it work.
EDITED template:
<template>
<div class="row">
</div>
<div class="col-12">
<div class="card">
<div class="card-header">
<h3 class="card-title">{{title}}</h3>
<div class="card-tools">
<b-button variant="primary" #click="newItem">New {{singular}}</b-button>
<div></div>
</div>
</div>
<div class="card-body table-responsive p-0">
<spinner v-if="$root.loading"></spinner>
<b-table ref="table" :items="products" :fields="fields" bordered hover :head-variant="'light'" responsive="sm" v-else>
<template v-slot:cell(index)="data">
{{ data.index + 1 }}
</template>
<template v-slot:cell(name)="data">
<b-img thumbnail fluid :src="getImageUrl(data.image)" alt="Image 1" class="thumb-img"></b-img>
{{data.name}}
</template>
<template v-slot:cell(weights)="data">
<span v-weights="data.item"></span>
</template>
<template v-slot:cell(default_weight)="data">
<span v-floatFormatter="data.default_weight"></span>{{data.unit.sname}}
</template>
<template v-slot:cell(status)="data">
<span v-if="data.status" class="text-success text-bold">Active</span>
<span class="text-danger" v-else>Inactive</span>
</template>
<template v-slot:cell(action)="data">
<a #click.prevent="editItem(data.index)"><i class="fa fa-edit" aria-hidden="true" title="Update product" v-b-tooltip.hover></i></a>
<a #click.prevent="assignWeights(data.index)"><i class="fa fa-balance-scale" title="Assign weights" aria-hidden="true" v-b-tooltip.hover></i></a>
</template>
</b-table>
</div>
</div>
</div>
</template>
I tried a lot, after all this, my code is working correctly now, this given below code is the right solution.
<b-table ref="table" :items="products" :fields="fields" bordered hover :head-variant="'light'" responsive="sm" v-else>
<template v-slot:cell(index)="data">
{{ data.index+1 }}
</template>
<template v-slot:cell(name)="data">
<b-img thumbnail fluid :src="getImageUrl(data.item.image)" alt="Image 1" class="thumb-img"></b-img>
{{data.item.name}}
</template>
<template v-slot:cell(weights)="data">
<span v-weights="data.item"></span>
</template>
<template v-slot:cell(default_weight)="data">
<span v-floatFormatter="data.item.default_weight"></span>{{data.item.unit.sname}}
</template>
<template v-slot:cell(status)="data">
<span v-if="data.status" class="text-success text-bold">Active</span>
<span class="text-danger" v-else>Inactive</span>
</template>
<template v-slot:cell(action)="data">
<a #click.prevent="editItem(data.item.id)"><i class="fa fa-edit" aria-hidden="true" title="Update product" v-b-tooltip.hover></i></a>
<a #click.prevent="assignWeights(data.item.id)"><i class="fa fa-balance-scale" title="Assign weights" aria-hidden="true" v-b-tooltip.hover></i></a>
</template>
</b-table>

b-table render all the data without respecting the fields

I am building a project using laravel and Vue JS to create a list of companies with pagination etc..
I am using bootstrap-table and the problem the table render all the data without respecting the fields that I am giving as a param. I want to use scope field to show a custom css inside every row. I use the same table with other data it works fine.
This is the component code
<template>
<div class="row">
<div class="col-lg-3 mt-lg-5">
<div class="card bord-rad-5">
<div class="card-header purple-background top-borders">
<h4
class="title-align font-montserrat text-light white-text-color mt-3 position-filter"
>
Filter
</h4>
</div>
<div class="card-body">
<div class="d-flex flex-column">
<div
class="gray-text-color font-weight-bold font-montserrat-regular mb-2"
>
<h5>{{ $t('labels.frontend.filters.companyName') }}</h5>
</div>
<div class="form-group">
<b-form-group class="ml-1">
<b-input-group>
<b-form-input v-model="filter" placeholder="Type to search">
</b-form-input>
<b-input-group class="mr-2">
<b-button
class="mr-left-90 mr-4 mt-2 font-montserrat-regular"
:disabled="!filter"
#click="filter = ''"
>
{{ $t('labels.frontend.companies.clear') }}
</b-button>
</b-input-group>
</b-input-group>
</b-form-group>
</div>
<div
class="gray-text-color font-weight-bold font-montserrat-regular mt-2 mb-2"
>
<h5>{{ $t('labels.frontend.filters.companyType') }}</h5>
</div>
<div class="form-check form-check-inline mt-1 mb-1">
<input
class="form-check-input"
type="checkbox"
id="ac1"
value="AssemblyCompany"
/>
<label
class="form-check-label gray-text-color font-weight-bold font-montserrat-thin"
for="ac1"
>
{{ $t('labels.frontend.filters.dismantling') }}
</label>
</div>
<div class="form-check form-check-inline mt-1 mb-1">
<input
class="form-check-input"
type="checkbox"
id="gd1"
value="garagebusiness"
/>
<label
class="form-check-label gray-text-color font-weight-bold font-montserrat-thin"
for="gd1"
>
{{ $t('labels.frontend.filters.garage') }}
</label>
</div>
<div class="form-check form-check-inline mt-1 mb-1">
<input
class="form-check-input"
type="checkbox"
id="rb1"
value="RevisionCompany"
/>
<label
class="form-check-label gray-text-color font-weight-bold font-montserrat-thin"
for="rb1"
>
{{ $t('labels.frontend.filters.revision') }}
</label>
</div>
</div>
</div>
</div>
</div>
<div class="mt-5 col-lg-9">
<div class="card-header purple-background bord-top-lr-5">
<b-row class="mt-2">
<b-col>
<h4 class="title-align font-montserrat text-light white-text-color">
{{ items.count }} {{ $t('labels.frontend.companies.results') }}
</h4>
</b-col>
<b-form-group label-cols-sm="3" class="mb-2 w-25 mr-4">
<b-form-select v-model="perPage" :options="pageOptions">
</b-form-select>
</b-form-group>
</b-row>
</div>
<div class="card-body white-bg">
<div class="grid-x grid-padding-x m-2 border-0">
<div class="border-0 mb-2">
<b-table
striped
hover
:items="items.data"
:fields="columns"
:filter="filter"
:current-page="currentPage"
:per-page="perPage"
:outlined="outlined"
responsive
>
<template slot="name" class="m-3" slot-scope="item">
<h5 class="title-align font-montserrat" style="color: #5b2557">
<a :href="data.item.url" :title="data.item.name">
{{ data.item.name }}
</a>
</h5>
<div class="row">
<div class="col">
<p
class="gray-text-color font-montserrat-thin font-weight-bold"
>
{{ data.item.street }}
{{ data.item.building_nr }} {{ data.item.postal }}
{{ data.item.city }} {{ data.item.state }}
</p>
</div>
<div class="col ml-lg-5">
<p
class="font-montserrat-thin blue-light-color font-weight-bold"
>
T. {{ data.item.phone }}<br />
<a
:href="data.item.website"
target="_blank"
:title="data.item.name"
class="gray-text-color"
>
{{ $t('labels.frontend.companies.goTo') }}
</a>
</p>
</div>
<div class="col ml-lg-5">
<a
class="font-montserrat-regular"
:href="
$app.route('frontend.companies.show', data.item.slug)
"
style="color: #74aee0"
>
{{ $t('labels.frontend.companies.moreInfo') }} »
</a>
</div>
</div>
<button
class="mb-3 blue-light-bg btn bord-rad-5 white-text-color font-montserrat-regular"
href="#"
>
{{ $t('labels.frontend.companies.stock') }}
</button>
<br />
</template>
</b-table>
<b-row>
<b-col md="6" class="my-1">
<b-pagination
v-model="currentPage"
:total-rows="totalRows"
:per-page="perPage"
class="my-0"
></b-pagination>
</b-col>
</b-row>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'SearchCompaniesTable',
props: {
companyName: {
type: String,
required: false,
default: () => ''
}
},
data() {
return {
filter: null,
totalRows: 1,
currentPage: 1,
perPage: 10,
pageOptions: [5, 10, 25],
outlined: true,
columns: [
{
field: 'name',
label: 'Name'
}
],
items: []
}
},
computed: {
rows() {
return Object.keys(this.items).length
}
},
mounted() {
axios.get('/companies/search').then(response => {
this.items = response.data
this.totalRows = this.items.count
console.log(this.fields)
})
}
}
</script>
<style>
.hidden_header {
display: none;
}
thead {
border: none !important;
}
tbody {
border: none !important;
border-color: white;
}
table {
border: none !important;
}
th {
border: none !important;
}
tr {
border: none !important;
}
td {
border: none !important;
}
.mr-left-90 {
margin-left: 68px;
}
.position-filter {
position: relative;
top: -8px;
}
</style>
could you please help me to find a solution for that ?
Here you can find the code for the component
<template>
<div class="row">
<div class="col-lg-3 mt-lg-5">
<div class="card bord-rad-5">
<div class="card-header purple-background top-borders">
<h4
class="title-align font-montserrat text-light white-text-color mt-3 position-filter"
>
Filter
</h4>
</div>
<div class="card-body">
<div class="d-flex flex-column">
<div
class="gray-text-color font-weight-bold font-montserrat-regular mb-2"
>
<h5>{{ $t('labels.frontend.filters.companyName') }}</h5>
</div>
<div class="form-group">
<b-form-group class="ml-1">
<b-input-group>
<b-form-input v-model="filter" placeholder="Type to search">
</b-form-input>
<b-input-group class="mr-2">
<b-button
class="mr-left-90 mr-4 mt-2 font-montserrat-regular"
:disabled="!filter"
#click="filter = ''"
>
{{ $t('labels.frontend.companies.clear') }}
</b-button>
</b-input-group>
</b-input-group>
</b-form-group>
</div>
<div
class="gray-text-color font-weight-bold font-montserrat-regular mt-2 mb-2"
>
<h5>{{ $t('labels.frontend.filters.companyType') }}</h5>
</div>
<div class="form-check form-check-inline mt-1 mb-1">
<input
class="form-check-input"
type="checkbox"
id="ac1"
value="AssemblyCompany"
/>
<label
class="form-check-label gray-text-color font-weight-bold font-montserrat-thin"
for="ac1"
>
{{ $t('labels.frontend.filters.dismantling') }}
</label>
</div>
<div class="form-check form-check-inline mt-1 mb-1">
<input
class="form-check-input"
type="checkbox"
id="gd1"
value="garagebusiness"
/>
<label
class="form-check-label gray-text-color font-weight-bold font-montserrat-thin"
for="gd1"
>
{{ $t('labels.frontend.filters.garage') }}
</label>
</div>
<div class="form-check form-check-inline mt-1 mb-1">
<input
class="form-check-input"
type="checkbox"
id="rb1"
value="RevisionCompany"
/>
<label
class="form-check-label gray-text-color font-weight-bold font-montserrat-thin"
for="rb1"
>
{{ $t('labels.frontend.filters.revision') }}
</label>
</div>
</div>
</div>
</div>
</div>
<div class="mt-5 col-lg-9">
<div class="card-header purple-background bord-top-lr-5">
<b-row class="mt-2">
<b-col>
<h4 class="title-align font-montserrat text-light white-text-color">
{{ items.count }} {{ $t('labels.frontend.companies.results') }}
</h4>
</b-col>
<b-form-group label-cols-sm="3" class="mb-2 w-25 mr-4">
<b-form-select v-model="perPage" :options="pageOptions">
</b-form-select>
</b-form-group>
</b-row>
</div>
<div class="card-body white-bg">
<div class="grid-x grid-padding-x m-2 border-0">
<div class="border-0 mb-2">
<b-table
striped
hover
:items="items.data"
:fields="columns"
:filter="filter"
:current-page="currentPage"
:per-page="perPage"
:outlined="outlined"
responsive
>
<template slot="name" class="m-3" slot-scope="item">
<h5 class="title-align font-montserrat" style="color: #5b2557">
<a :href="data.item.url" :title="data.item.name">
{{ data.item.name }}
</a>
</h5>
<div class="row">
<div class="col">
<p
class="gray-text-color font-montserrat-thin font-weight-bold"
>
{{ data.item.street }}
{{ data.item.building_nr }} {{ data.item.postal }}
{{ data.item.city }} {{ data.item.state }}
</p>
</div>
<div class="col ml-lg-5">
<p
class="font-montserrat-thin blue-light-color font-weight-bold"
>
T. {{ data.item.phone }}<br />
<a
:href="data.item.website"
target="_blank"
:title="data.item.name"
class="gray-text-color"
>
{{ $t('labels.frontend.companies.goTo') }}
</a>
</p>
</div>
<div class="col ml-lg-5">
<a
class="font-montserrat-regular"
:href="
$app.route('frontend.companies.show', data.item.slug)
"
style="color: #74aee0"
>
{{ $t('labels.frontend.companies.moreInfo') }} »
</a>
</div>
</div>
<button
class="mb-3 blue-light-bg btn bord-rad-5 white-text-color font-montserrat-regular"
href="#"
>
{{ $t('labels.frontend.companies.stock') }}
</button>
<br />
</template>
</b-table>
<b-row>
<b-col md="6" class="my-1">
<b-pagination
v-model="currentPage"
:total-rows="totalRows"
:per-page="perPage"
class="my-0"
></b-pagination>
</b-col>
</b-row>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'SearchCompaniesTable',
props: {
companyName: {
type: String,
required: false,
default: () => ''
}
},
data() {
return {
filter: null,
totalRows: 1,
currentPage: 1,
perPage: 10,
pageOptions: [5, 10, 25],
outlined: true,
columns: [
{
field: 'name',
label: 'Name'
}
],
items: []
}
},
computed: {
rows() {
return Object.keys(this.items).length
}
},
mounted() {
axios.get('/companies/search').then(response => {
this.items = response.data
this.totalRows = this.items.count
console.log(this.fields)
})
}
}
</script>
What mistake i am doing and thank you for answering
In your first code snippet your style is not using the scoped attribute, which may mean the rest of your project is doing he same thing. This could mean that your CSS is being overwritten at the global level, If you inspect the element after render can you see if your CSS is being overwritten somewhere.
Also, if you happen to be using SCSS the bootstrap-vue library supports it very well and I have found it to be easier to adjust the bootstrap css easier.
I fixed the problem by changing the code inside the template tag from <template slot="name" slot-scope="item"> to <template v-slot:cell(name)="data">

VueJS: how to toggle "collapse" of different components? (if X is show then Y is hide, vice versa)

I'm very new to VueJS and trying to re-engineer an old site into VueJS 2.
My first issue is how to replicate what I did in JQuery, where by:
if component X 'display' is true, then component Y 'display' is false, and vice versa.
Essentially, if I click a button to expand the b-collapse "cccollapse" element, then I want the "szcollapse" element to collapse (if it is expanded) and vice versa, so only one of those collapsible elements is "extended" at a given point in time.
I'm using bootstrap-vue in my Vue project and this is what the current template looks like this:
<template>
<div>
<b-container fluid class="button-row">
<fieldset>
<legend class="scheduler-border">
<span class="legend-label">YOU : MANAGE YOUR KEYS</span>
</legend>
<b-row class="menu-row">
<b-col>
<b-button variant="primary" size="lg" block class="text-left button-custom"><i style="padding-right:10px;padding-left:30%;" class="fas fa-plus-circle"></i>REQUEST A KEY</b-button>
</b-col>
</b-row>
<b-row class="menu-row">
<b-col>
<b-button v-b-toggle.szcollapse v-on:click="collapseCCCollapse" variant="primary" size="lg" block class="text-left button-custom"><i style="padding-right:10px;padding-left:30%;" class="fas fa-share-square"></i>ISSUE A KEY</b-button>
<b-collapse ref="szcollapse" id="szcollapse" class="mt-2">
<b-container class="container-sz-login">
<b-row class="cred-dropdown">
<b-col>
<b-input-group>
<span class="input-group-text" id="basic-addon1">
<i class="fas fa-user-circle fa-fw"></i>
</span>
<b-form-input id="txtUsername" />
</b-input-group>
</b-col>
</b-row>
<b-row class="cred-dropdown">
<b-col>
<b-input-group>
<span class="input-group-text" id="basic-addon1">
<i class="fas fa-lock fa-fw"></i>
</span>
<b-form-input type="password" id="txtPassword" />
</b-input-group>
</b-col>
</b-row>
<b-row class="cred-dropdown">
<b-col cols="2"/>
<b-col cols="8">
<b-button variant="primary" id="szlogin" size="lg" block >LOGIN<i style="padding-left:5px;" class="fas fa-sign-in-alt"></i></b-button>
</b-col>
<b-col cols="2"/>
</b-row>
</b-container>
</b-collapse>
</b-col>
</b-row>
<b-row class="menu-row">
<b-col>
<b-button v-b-toggle.cccollapse v-on:click="collapseSZCollapse" variant="primary" size="lg" block class="text-left button-custom"><i style="padding-right:10px;padding-left:30%;" class="fas fa-network-wired"></i>MANAGE YOUR KEYS</b-button>
<b-collapse ref="cccollapse" id="cccollapse" class="mt-2" v-model="showCollapse">
<b-container class="container-sz-login">
<b-row class="cred-dropdown">
<b-col>
<b-input-group>
<span class="input-group-text" id="basic-addon1">
<i class="fas fa-user-circle fa-fw"></i>
</span>
<b-form-input id="txtCorpId"/>
</b-input-group>
</b-col>
</b-row>
<b-row class="cred-dropdown">
<b-col>
<b-input-group>
<span class="input-group-text" id="basic-addon1">
<i class="fas fa-lock fa-fw"></i>
</span>
<b-form-input type="password" id="txtCorpPwd"/>
</b-input-group>
</b-col>
</b-row>
<b-row class="cred-dropdown">
<b-col cols="2"/>
<b-col cols="8">
<b-button variant="primary" id="ccLogin" size="lg" block >LOGIN<i style="padding-left:5px;" class="fas fa-sign-in-alt"></i></b-button>
</b-col>
<b-col cols="2"/>
</b-row>
</b-container>
</b-collapse>
</b-col>
</b-row>
</fieldset>
</b-container>
</div>
</template>
And this is the script:
<script>
export default {
name: "Menu",
props: {
msg: String
},
methods: {
collapseSZCollapse : function() {
console.log('this.$refs.szcollapse : ' + this.$refs.szcollapse.collapsed);
},
collapseCCCollapse : function() {
console.log('this.$refs.cccollapse : ' + this.$refs.cccollapse.collapsed)
}
},
data() {
return {
showCollapse: false
};
}
};
</script>
Obviously the script isnt really doing anything in the methods -- i'm just trying to see how to get the value of the current element to make a decision when v-on:click is called.
What is the correct VueJS way of doing this? I understand (sort of) that vuejs is data driven, but I'm not sure how to get the data from one element to drive the state of the other.
Sigh. If I had actually investigated properly...
https://bootstrap-vue.js.org/docs/components/collapse/#accordion-support
This does exactly what I want.
Still happy to hear other programmatic answers if there are any?
You can give your b-collapse element a v-model binding. Here's a jsfiddle showing an example.
new Vue({
el: "#app",
data: {
firstCollapsed: true,
secondCollapsed: false
},
methods: {
alternateCollapse() {
if (this.firstCollapsed) {
this.firstCollapsed = false;
this.secondCollapsed = true;
} else {
this.firstCollapsed = true;
this.secondCollapsed = false;
}
}
}
});
<div id="app">
<b-collapse v-model="firstCollapsed" id="collapse1">
<div>Inner Element 1</div>
</b-collapse>
<b-collapse v-model="secondCollapsed" id="collapse2">
<div>Inner Element 2</div>
</b-collapse>
<b-btn #click="alternateCollapse()">Alternate Collapse</b-btn>
</div>
<style scoped>
.collapse {
margin: 5px;
padding: 5px;
background-color: lightgray;
}
#collapse1 {
border: 1px solid red;
}
#collapse2 {
border: 1px solid blue;
}
</style>

How to add number or id each element in vue js?

in my case i create dynamic form (like todo app) in another components. i want accesibility for other actions. therefore i must set id or number each created element(div). when i add increment method console shows duplicate key error.
how can i add number or id each element?
For examples: this is 1. created element,
this is 2. created element,
this is 3. created element,
some codes:
methods: {
...mapActions(["setAdList"]),
ilanVer() {
this.alert = true;
let adListObj = {
adName: this.adName,
text: this.text,
province: this.province,
education: this.education,
solder: this.solder,
id: this.id
}
this.setAdList(adListObj);
this.id += 1;
console.log(this.id)
},
}
<template>
<!-- eslint-disable max-len -->
<div class="ad-box">
<h1 class="d-flex justify-content-center align-items-center mt-2">İlanlarım</h1>
<hr />
<div class="ilan-list">
<b-card :title=item.adName v-for="(item) in adList" :key="item.id" class="border border-info rounded w-50">
<b-badge class="ml-3">{{item.id}}</b-badge>
<p class="card-text">Aday Özellikleri: <span class="text-center">{{item.text}}</span> </p>
<p class="card-text">Şehir: {{item.province}}</p>
<p class="card-text">Eğitim: {{item.education}}</p>
<p class="card-text">Askerlik: {{item.solder}}</p>
<router-link to="/ilandetayi/:id">
<b-button class="btn-outline-success mr-2">İlanlarıma Git</b-button>
</router-link>
</b-card>
<hr />
</div>
</div>
</template>
You can use index when using v-for directive
In your case
v-for="(item, index) in adList" and then inside the block index will have values 0, 1, 2, ....
You can use Index item of v-for to define the unique id
v-for="(item, index) in adList" :key="index"
<template> <!-- eslint-disable max-len --> <div class="ad-box">
<h1 class="d-flex justify-content-center align-items-center mt-2">İlanlarım</h1>
<hr />
<div class="ilan-list">
<b-card :title=item.adName v-for="(item, index) in adList" :key="index" class="border border-info rounded w-50">
<b-badge class="ml-3">{{item.id}}</b-badge>
<p class="card-text">Aday Özellikleri: <span class="text-center">{{item.text}}</span> </p>
<p class="card-text">Şehir: {{item.province}}</p>
<p class="card-text">Eğitim: {{item.education}}</p>
<p class="card-text">Askerlik: {{item.solder}}</p>
<router-link to="/ilandetayi/:id">
<b-button class="btn-outline-success mr-2">İlanlarıma Git</b-button>
</router-link>
</b-card>
<hr />
</div> </div> </template
> Blockquote