【问题标题】:Binding a Select2 select to a Vue js model data将 Select2 选择绑定到 Vue js 模型数据
【发布时间】:2015-10-14 23:33:15
【问题描述】:

我正在使用 select2 来增强 html 选择元素。我想将 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>");
    }
  }
});
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>

【问题讨论】:

标签: javascript jquery jquery-select2 vue.js


【解决方案1】:

更短的解决方案:

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】:

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

    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>

    【讨论】:

      【解决方案3】:

      此解决方案适用于 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");
      

      【讨论】:

      • 虽然这个可能有效,但问题是关于 Select2 的问题,并且 Select2 和 Chosen 之间有足够的区别,需要进行哪些更改并不明显。跨度>
      • 很容易看出需要进行哪些更改。考虑以下内容: .chosen({ inherit_select_classes: true, width: '30%', disable_search_threshold: 999 }) 这些是 Chosen 的参数。只需将它们替换为 Select2 的参数即可。唯一需要替换的是 $(this.el).trigger("chosen:updated"); 行,它必须替换为通知 Select2 更新的代码。
      • 这是一个Select2问题,未选择。此代码需要进行哪些更改才能使其与 Select2 一起使用?
      【解决方案4】:

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

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

      希望对你有帮助!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-12-18
        • 2019-02-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-07
        相关资源
        最近更新 更多