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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31608076/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 14:03:07  来源:igfitidea点击:

Binding a Select2 select to a Vue js model data

javascriptjqueryjquery-select2vue.js

提问by harryg

I'm using select2 to enhance an html select element. I want to bind the value of the select element to a Vue variable, however the Select2 seems to be preventing this.

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

What's the best way to achieve this data binding and event listening whilst retaining the Select2 behaviour. I imagine it's a case of linking the select2 events to the Vue instance.

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

I've made a fiddledemonstrating the problem (does not run below but works on jsfiddle):

我制作了一个小提琴来演示这个问题(不在下面运行,但可以在 jsfiddle 上运行):

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

new Vue({
  el: "#vue-example",
  data: {
    thing: null,
    thing2: null
  },
  methods: {
    log: function(str) {
      $('#log').append(str + "<br>");
    }
  }
});
select {
  width: 50%;
}
<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>

回答by Wiktor Zawierucha

A shorter solution:

更短的解决方案:

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's answer is good but the value is already being stored on the select element, so all you have to do, is dispatch the event to let Vue know that we have changed it.

Trae 的回答很好,但是值已经存储在 select 元素上,所以你要做的就是调度事件让 Vue 知道我们已经改变了它。

Just simply do:

只需简单地做:

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

回答by Trae

swift's answer is correct. You just need to identify and update that code to reflect the differences in Select2.

斯威夫特的回答是正确的。您只需要识别和更新该代码以反映 Select2 中的差异。

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

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

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>");
    }
  }
});
select {
  width: 50%;
}
<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>

回答by swift

This solution works for the Chosen plugin, but you can do the same thing with Select2 to make it work:

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

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

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");

回答by Jorge Ramón

I made a plugin for select2 a few days ago.

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

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

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

Hope it helps!

希望能帮助到你!