更改事件上的 Select2 在 Vuejs 中不起作用

Posted

技术标签:

【中文标题】更改事件上的 Select2 在 Vuejs 中不起作用【英文标题】:Select2 on change event is not working in 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>

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

【问题讨论】:

【参考方案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");   
  

【讨论】:

以上是关于更改事件上的 Select2 在 Vuejs 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

select2 和表单更改事件

VueJS Select2 指令不会触发 @change 事件

Select2 自动触发事件变化

清除 select2 而不触发更改事件

如何使用 Vuejs 在 Safari 中侦听表单上的粘贴事件

Select2 更改事件 - 在第一个 select2 框值更改时更改下一个 select2 框的选项