【问题标题】:Select2 on change event is not working in Vuejs更改事件上的 Select2 在 Vuejs 中不起作用
【发布时间】:2017-04-19 19:43:17
【问题描述】:

我在 vuejs 中使用 select2,我发现 vuejs 无法使用 jquery select2,因为 vuejs 正在使用 navite html。

我正在使用此代码

Vue.directive('select', {
        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");
        }
    });
    var app = new Vue({
      el: '#app',
      data: {
        supplier_id: "niklesh"
      }
    })
    $('#supplier_id').select2({});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.4/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.5/css/bootstrap.css">
<div id="app">
  {{ supplier_id }}

<select id="supplier_id" class='form-control' v-model='supplier_id' v-select='supplier_id'>
    <option value="atul">Atul</option>
    <option value="niklesh">Niklesh</option>
    <option value="sachin">Sachin</option>
</select>

</div>

请分享您的回复以处理此问题。

【问题讨论】:

    标签: javascript jquery html vue.js jquery-select2


    【解决方案1】:

    要让它与指令一起使用,我们需要了解v-model 的工作原理。来自docs

    <input v-model="something">
    

    只是语法糖:

    <input v-bind:value="something" v-on:input="something = $event.target.value">
    

    对于选择元素,v-model 将侦听change 事件(而不是input)。因此,如果指令在元素更改时调度 change 事件,则 v-model 将按预期工作。

    这是您的代码的更新版本(适用于 Vue 2):

    Vue.directive('select', {
      twoWay: true,
      bind: function (el, binding, vnode) {
        $(el).select2().on("select2:select", (e) => {
          // v-model looks for
          //  - an event named "change"
          //  - a value with property path "$event.target.value"
          el.dispatchEvent(new Event('change', { target: e.target }));
        });
      },
      componentUpdated: function(el, me) {
        // update the selection if the value is changed externally
        $(el).trigger("change");
      }
    });
    var app = new Vue({
      el: '#app',
      data: {
        supplier_id: "niklesh"
      },
    })
    $('#supplier_id').select2({});
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.4/vue.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.5/css/bootstrap.css">
    <div id="app">
      {{ supplier_id }}
    
      <select id="supplier_id" class='form-control' v-model='supplier_id' v-select='supplier_id'>
        <option value="atul">Atul</option>
        <option value="niklesh">Niklesh</option>
        <option value="sachin">Sachin</option>
      </select>
    
    </div>

    这是一个适用于 Vue 3 的版本(自定义指令有不同的语法,linked here):

    var app = Vue.createApp({
      data: function() { 
        return {
          supplier_id: "niklesh"
        }
      }
    })
    
    app.directive('select', {
      beforeMount: function (el, binding, vnode) {
        $(el).select2().on("select2:select", (e) => {
          // v-model looks for
          //  - an event named "change"
          //  - a value with property path "$event.target.value"
          el.dispatchEvent(new Event('change', { target: e.target }));
        });
      },
        updated: function(el) {
        // update the selection if the value is changed externally
        $(el).trigger("change");
      }
    });
    
    app.mount('#app');
    
    $('#supplier_id').select2({});
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.js"></script>
    <script src="https://unpkg.com/vue@3.0.11"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.5/css/bootstrap.css">
    <div id="app">
      {{ supplier_id }}
    
      <select id="supplier_id" class='form-control' v-model='supplier_id' v-select='supplier_id'>
        <option value="atul">Atul</option>
        <option value="niklesh">Niklesh</option>
        <option value="sachin">Sachin</option>
      </select>
    
    </div>

    【讨论】:

    • 感谢您的解决方案!我正在使用多选,所以我还必须在select2:unselect 上触发更改事件,如下所示:$(el).select2().on("select2:select select2:unselect", (e) =&gt; {
    • 这似乎不适用于 Vue3。任何想法为什么?
    • @e4rthdog 指令在 Vue 3 中的工作方式不同。我为 Vue 3 添加了代码 sn-p。
    【解决方案2】:

    通过将 select2 值分配给 vuejs 数据,我能够解决这个问题。我这里没有使用自定义指令。

    var app = new Vue({
      el: '#app',
      data: {
        supplier_id: "niklesh"
      },
      filters: {
        capitalize: function (value) {
          if (!value) return ''
          value = value.toString()
          return value.charAt(0).toUpperCase() + value.slice(1)
        }
      }
    });
    
    $('#supplier_id').on("change",function(){
        app.supplier_id = $(this).val();
        console.log('Name : '+$(this).val());
    });
    
    $('#supplier_id').select2({});
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.4/vue.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.5/css/bootstrap.css">
    <div id="app">
      Name : {{ supplier_id | capitalize }}
    <select id="supplier_id" class='form-control' v-model='supplier_id'>
        <option value="atul">Atul</option>
        <option value="niklesh">Niklesh</option>
        <option value="sachin">Sachin</option>
    </select>
    
    </div>

    如果这不是好方法或您建议的任何更好的解决方案,请发表评论。

    【讨论】:

    • 1 分钟前提出并回答?
    • @darryn.ten:这是我自己的答案,虽然它通过 jquery 工作,但如果我能通过 vuejs 解决这个问题,我会很棒。
    • @Rishi:我认为这不是一个糟糕的解决方案,但您最初使用指令的想法似乎更可重用。我添加了一个解决方案,展示了如何改用指令。
    【解决方案3】:
    <select v-model="selected">
           <option value="1">1</option>
           <option value="2">2</option>
           <option value="3">3</option>
    </select>
    
    
    const self = this;
    $("select").change(function () {
            const val = $(this).find("option:selected").val();
            self.selected = val;
     });
    

    【讨论】:

    • 通过解释它为什么起作用以及为什么它比公认的答案更好的方法,可以改进这个答案。
    • 最简单最简单的解决方案。谢谢。
    【解决方案4】:

    尝试在您的选择控件中添加v-on:change="onChange"

    HTML 模板

    <select id="supplier_id" class='form-control' 
    v-model='supplier_id' v-select='supplier_id' v-on:change="onChange">
        <option value="atul">Atul</option>
        <option value="niklesh">Niklesh</option>
        <option value="sachin">Sachin</option>
    </select>
    

    “onChange”是你方法的名字

    JavaScript

    methods: {
      onChange(e) {        
          alert("Change");   
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2021-09-10
      • 1970-01-01
      • 1970-01-01
      • 2018-09-05
      • 2012-12-10
      • 1970-01-01
      • 1970-01-01
      • 2018-06-15
      • 2018-03-06
      相关资源
      最近更新 更多