I create dynamic component using Vue and Bootstrap Tokenfield. But v-model
doesn't work in this case.
Assume, I have an array below:
index variant_options
1 aaa
2 sss
When I remove index 1, the result of index 1 should be "sss" but still "aaa"
<div class="card" v-for="(variant, index) in form.variants" :key="index">
<div class="card-body"> <span class="float-right" style="cursor: pointer" @click="deleteVariant(index)">
X
</span>
<div class="row">
<div class="col-md-4">
<label for="weight">Variant Type {{ index + 1 }} </label>
<div class="input-group">
<input type="text" id="variant_type" class="form-control" v-model="
variant.variant_type
" @keyup="tokenField()" placeholder="Input variant type. E.g: Color" name="name" required autofocus /> </div>
</div>
<div class="col-md-8">
<label for="weight">Variant Options {{ index + 1 }}</label>
<div class="input-group">
<input type="text" id="variant_options" autofocus="true" v-model="
variant.variant_options
" @mouseover="
tokenField()
" placeholder="Input variant options. E.g: Blue, Brown," class="
form-control
variant_options
" /> </div>
data() {
return {
form: new Form({
variants: [
{
variant_type: '',
variant_options: '',
},
],
}),
};
},
methods: {
tokenField() {
$('.variant_options').tokenfield({
showAutocompleteOnFocus: true,
});
},
addVariant() {
if (this.form.variants.length <= 1) {
this.form.variants.push({
variant_type: '',
variant_options: '',
});
} else {
this.error = 'You can only add 2 type of varians';
$('#errMsg').show();
}
},
deleteVariant(index) {
this.form.variants.splice(index, 1);
$('#errMsg').hide();
},
}, // methods:
When rendering list using v-for
do not use index
variable from v-for
as :key
, especially not when loop content contains any <input>
element and/or you are adding/removing/sorting items...
See the docs - Maintaining State
Note that the docs does not mention or discourage using index
variable as :key
in any way. But if you think about it, using index
is indeed same as not using :key
at all. Because role of :key
is to establish relationship (identity) between each item used in the loop and the DOM that is generated for it. This is something index
can't do...
key
should be stable (not change over time) and unique over all the items in the list. Sometime the data already contain such item (for example when the data comes from server/database). If there is no data property with above mentioned features (as in your case where both variant_type
and variant_options
are editable by the user), just generate your own artificial key. There are multiple ways to generate unique id in JS
Example using "running index":
data() {
return {
nextId: 1,
form: new Form({
variants: [
{
id: 0,
variant_type: '',
variant_options: '',
},
],
}),
};
},
methods: {
addVariant() {
if (this.form.variants.length <= 1) {
this.form.variants.push({
id: this.nextId++,
variant_type: '',
variant_options: '',
});
} else {
this.error = 'You can only add 2 type of varians';
$('#errMsg').show();
}
},
}
...and use :key="variant.id"
in the template