0
votes

I've created a wrapped vue component in laravel in order to wrap jQuery select2 element. Based in this code.

When the values in select.options change, the select element is duplicated. Like the following image. enter image description here

The selection only works in the second select.

I don't know what is the problem, I add below the code I have made and the content of the options variable.

select2.vue

<template>
    <div>
        <select>
            <slot></slot>
        </select>
    </div>

</template>
<script>
    export default {
        name: "select2",
        props: ['options', 'value'],
        mounted: function () {
            let vm = this
            $(this.$el)
                // init select2
                .select2({ data: this.options })
                .val(this.value)
                .trigger('change')
                // emit event on change.
                .on('change', function () {
                    vm.$emit('input', this.value)
                })
        },
        watch: {
            value: function (value) {
                // update value
                $(this.$el)
                    .val(value)
                    .trigger('change')
            },
            options: function (options) {
                // update options
                $(this.$el).empty().select2({ data: options })
            }
        },
        destroyed: function () {
            $(this.$el).off().select2('destroy')
        }

    }
</script>

<style scoped>

</style>

blade file call

<select2 :options="select.options" v-model="select.value"></select2>

select.options data

          [
                {
                    "text": "Group 1",
                    "children": [
                        {
                            "id": 1,
                            "text": "Element 1"
                        },
                        {
                            "id": 2,
                            "text": "Element 2"
                        }
                    ]
                },
                {
                    "text": "Group 2",
                    "children": [
                        {
                            "id": 3,
                            "text": "Element 3"
                        },
                        {
                            "id": 4,
                            "text": "Element 4"
                        }
                    ]
                }
            ]
1

1 Answers

1
votes

I tried for a while to reproduce the problem you were having, without any success.

I noticed a couple of things that might help you:

this.$el refers to the div in your example, where as the examples I've seen use select.

Try and avoid using the same names for properties and variables, as this makes it confusing options: function (options) {

I've included a snippet below in case it helps.

Vue.config.productionTip = false;
Vue.config.devtools = false;

Vue.component("select2", {
  template: "<select style='width: 100%'></select>",
  props: ['options', 'value'],
  mounted: function() {
    let vm = this
    $(this.$el)
      .select2({
        data: this.options
      })
      .val(this.value)
      .trigger('change')
      .on('change', function() {
        vm.$emit('input', this.value)
      })
  },
  watch: {
    value: function(value) {
      $(this.$el)
        .val(value)
        .trigger('change')
    },
    options: function(val) {
      $(this.$el).empty().select2({
        data: val
      })
    }
  },
  destroyed: function() {
    $(this.$el).off().select2('destroy')
  }
});


new Vue({
  el: "#app",
  data: () => {
    return {
      selected: null,
      options: [{
          "text": "Group 1",
          "children": [{
              "id": 1,
              "text": "Element 1"
            },
            {
              "id": 2,
              "text": "Element 2"
            }
          ]
        },
        {
          "text": "Group 2",
          "children": [{
              "id": 3,
              "text": "Element 3"
            },
            {
              "id": 4,
              "text": "Element 4"
            }
          ]
        }
      ]
    }
  },
  methods: {
  modifyOptions() {
  this.options = [{
          "text": "Group 1",
          "children": [{
              "id": 4,
              "text": "Element 1"
            },
            {
              "id": 6,
              "text": "Element 2"
            }
          ]
        }];
  }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/select2.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <div>
    <select2 :options="options" v-model="selected"></select2>
    <div>
    Selected: {{selected}}
    </div>
    <button type="button" @click="modifyOptions">Modify Options</button>
  </div>
</div>