将Select2选择绑定到Vue js模型数据

时间:2015-07-24 10:23:20

标签: javascript jquery jquery-select2 vue.js

我使用select2来增强html select元素。我想将select元素的值绑定到Vue变量,但Select2似乎阻止了这一点。

在保留Select2行为的同时,实现此数据绑定和事件监听的最佳方式是什么。我想这是将select2事件链接到Vue实例的情况。

我已经a fiddle证明了这个问题(不在下面运行但是在jsfiddle上工作):



$('#things').select2();

new Vue({
  el: "#vue-example",
  data: {
    thing: null,
    thing2: null
  },
  methods: {
    log: function(str) {
      $('#log').append(str + "<br>");
    }
  }
});
&#13;
select {
  width: 50%;
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/0.12.8/vue.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>

<div id="vue-example">
  <label>Select2 Select Box</label>
  <select name="things" id="things" v-model="thing" v-on="change: log('you changed thing1')">
    <option value="1">One</option>
    <option value="2">Two</option>
    <option value="3">Three</option>
    <option value="4">Four</option>
    <option value="5">Five</option>
  </select>
  <br>
  <br>
  <label>Native Select Box</label>
  <select name="things" id="things" v-model="thing2" v-on="change: log('you changed thing2')">
    <option value="1">One</option>
    <option value="2">Two</option>
    <option value="3">Three</option>
    <option value="4">Four</option>
    <option value="5">Five</option>
  </select>
  <pre>{{ $data | json }}</pre>
  <div id="log">

  </div>
</div>
&#13;
&#13;
&#13;

4 个答案:

答案 0 :(得分:8)

快速的回答是正确的。您只需要识别并更新该代码以反映Select2中的差异。

http://jsfiddle.net/qfy6s9Lj/10/

&#13;
&#13;
Vue.directive('selecttwo', {
  twoWay: true,
  bind: function () {
    $(this.el).select2()
    .on("select2:select", function(e) {
      this.set($(this.el).val());
    }.bind(this));
  },
  update: function(nv, ov) {
    $(this.el).trigger("change");
  }
});

new Vue({
  el: "#vue-example",
  data: {
    thing: null,
    thing2: null
  },
  methods: {
    log: function(str) {
      $('#log').append(str + "<br>");
    }
  }
});
&#13;
select {
  width: 50%;
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/0.12.8/vue.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>

<div id="vue-example">
  <label>Select2 Select Box</label>
  <select name="things" id="things" v-model="thing" v-selecttwo="thing" v-on="change: log('you changed thing1')">
    <option value="1">One</option>
    <option value="2">Two</option>
    <option value="3">Three</option>
    <option value="4">Four</option>
    <option value="5">Five</option>
  </select>
  <br>
  <br>
  <label>Native Select Box</label>
  <select name="things" id="things" v-model="thing2" v-selecttwo="thing2" v-on="change: log('you changed thing2')">
    <option value="1">One</option>
    <option value="2">Two</option>
    <option value="3">Three</option>
    <option value="4">Four</option>
    <option value="5">Five</option>
  </select>
  <pre>{{ $data | json }}</pre>
  <div id="log">

  </div>
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:5)

一个简短的解决方案:

Vue.directive('select2', {
    inserted(el) {
        $(el).on('select2:select', () => {
            const event = new Event('change', { bubbles: true, cancelable: true });
            el.dispatchEvent(event);
        });

        $(el).on('select2:unselect', () => {
            const event = new Event('change', {bubbles: true, cancelable: true})
            el.dispatchEvent(event)
        })
    },
});

Trae的答案很好,但是值已经存储在select元素上,因此您要做的就是调度事件,让Vue知道我们已对其进行了更改。

只需执行以下操作

<select v-model="myprop" v-select2>
...

答案 2 :(得分:2)

此解决方案适用于Chosen插件,但您可以使用Select2执行相同的操作:

http://jsfiddle.net/simplesmiler/qfy6s9Lj/8/

Vue.directive('chosen', {
    twoWay: true, // note the two-way binding
    bind: function () {
        $(this.el)
            .chosen({
                inherit_select_classes: true,
                width: '30%',
                disable_search_threshold: 999
            })
            .change(function(ev) {
                // two-way set
                this.set(this.el.value);
            }.bind(this));
    },
    update: function(nv, ov) {
        // note that we have to notify chosen about update
        $(this.el).trigger("chosen:updated");
    }
});

var vm = new Vue({
  data: {
      city: 'Toronto',
      cities: [{text: 'Toronto', value: 'Toronto'}, 
               {text: 'Orleans', value: 'Orleans'}]
  }
}).$mount("#search-results");

答案 3 :(得分:0)

我几天前为select2制作了一个插件。

https://github.com/halupi/vue-select2

希望它有所帮助!