har*_*ryg 6 javascript jquery jquery-select2 vue.js
我正在使用select2来增强html选择元素.我想将select元素的值绑定到Vue变量,但是Select2似乎阻止了这一点.
在保留Select2行为的同时,实现此数据绑定和事件监听的最佳方法是什么.我想这是将select2事件链接到Vue实例的情况.
我已经做了一个演示问题的小提琴(不在下面运行,但在jsfiddle上工作):
$('#things').select2();
new Vue({
el: "#vue-example",
data: {
thing: null,
thing2: null
},
methods: {
log: function(str) {
$('#log').append(str + "<br>");
}
}
});Run Code Online (Sandbox Code Playgroud)
select {
width: 50%;
}Run Code Online (Sandbox Code Playgroud)
<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>Run Code Online (Sandbox Code Playgroud)
小智 8
斯威夫特的回答是正确的.您只需要识别并更新该代码以反映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>");
}
}
});Run Code Online (Sandbox Code Playgroud)
select {
width: 50%;
}Run Code Online (Sandbox Code Playgroud)
<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>Run Code Online (Sandbox Code Playgroud)
小智 7
更短的解决方案:
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)
})
},
});
Run Code Online (Sandbox Code Playgroud)
Trae的答案很好但是值已经存储在select元素上了,所以你要做的就是派遣事件让Vue知道我们已经改变了它.
只需简单地做:
<select v-model="myprop" v-select2>
...
Run Code Online (Sandbox Code Playgroud)
此解决方案适用于 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");
Run Code Online (Sandbox Code Playgroud)