For many days I've searched to find an answer to this error. I tried many alternatives but nothing worked.
I need to select multiple values. When I select multiple values, my code hangs, but when I use a single select it works well with self.$emit('input', this.value)
. What I need is to select multiple values.
Select2.vue
<template>
<select multiple class="input-sm" :name="name">
<slot></slot>
</select>
</template>
<style src="select2/dist/css/select2.min.css"></style>
<style src="select2-bootstrap-theme/dist/select2-bootstrap.min.css"></style>
<script>
import Select2 from 'select2';
export default{
twoWay: true,
priority: 1000,
props: ['options', 'value', 'name'],
data(){
return{
msg: 'hello'
}
},
mounted(){
var self = this;
$(this.$el)
.select2({theme: "bootstrap", data: this.options})
.val(this.value)
.trigger('change')
.on('change', function () {
//self.$emit('input', this.value) //single select worked good
self.$emit('input', $(this).val()) // multiple select
})
},
watch: {
value: function (value) {
$(this.$el).val(value).trigger('change');
},
options: function (options) {
$(this.$el).select2({ data: options })
}
},
destroyed: function () {
$(this.$el).off().select2('destroy')
}
}
</script>
new.vue
<p>Selected: {{ model.users_id }}</p>
<select2 :options="options" v-model="model.users_id" name="options[]" style="width: 1000px; height: 1em;" class="form-control">
<option value="0">default</option>
</select2>
export default {
data(){
return {
model: {
'users_id': [],
},
options: [],
components:{
'select2': Select2
},
It looks like you used the Vue documentation example of a wrapper for select2 as your base. I've modified the wrapper to handle a multiple select here.
I expect the main issue you were running into is that if you do this:
self.$emit('input', $(this).val()) // multiple select
You will end up in an infinite loop, because you are emitting a new array, which is going to trigger the watch,
value: function (value) {
$(this.$el).val(value).trigger('change');
},
which triggers the change, which triggers the watch, etc.
To fix that, just check to see if the value passed into the watch is identical to the values of the select, and if it is, ignore it. Here's how I did that.
value: function (value) {
// check to see if the arrays contain the same values
if ([...value].sort().join(",") !== [...$(this.$el).val()].sort().join(","))
$(this.$el).val(value).trigger('change');
},
Notice also that I turned this into it's own component, select2Multiple
. You might want to have one component that handles multiple selected values and another for single values.
As I answered here: Using Select2 (multiple selections) with vue.js
Change this:
.on('change', function () {
self.$emit('input', this.value); // Don't use this.value
});
To this:
.on('change', function () {
self.$emit('input', $(this).val());
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With