我最近正在尝试在某些实际应用程序中重用我的Vue组件,以消除不必要的重复内容并用<divs>
弄乱。
但是我这样做很麻烦。几个小时后,我设法“完成”它,但是现在事件触发了两次,我不知道为什么。
我已经进行了基本设置以显示问题:
Vue.component("bs-select",{
template:
`<div class="form-group">
<label class="control-label">{{ label }}</label>
<select2
ref="select2control"
:options="options"
:value="value"
@input="chosenOption"
></select2>
</div>`,
props: ["value", "label", "options"],
methods: {
chosenOption(val) {
this.$emit("input", val);
}
}
});
Vue.component("select2",{
template:
`<select :value="value" style="width: 100%">
<option value="" selected disabled>Choose...</option>
<option v-if="!options">{{ value }}</option>
<option v-for="option in options" :value="option.value">{{ option.text }}</option>
</select>`,
props: ["value", "options"],
mounted: function() {
const vm = this;
$(vm.$el)
.select2()
.on("change", function() {
console.log("CHANGE", vm.$el.value);
vm.$emit("input", vm.$el.value);
});
},
watch: {
value: function(val) {
$(this.$el)
.val(val)
.trigger("change");
}
}
});
new Vue({
el: "#app",
data: {
test: "bug",
options: [
{
value: "hello",
text: "Hello"
},
{
value: "bug",
text: "Bug"
}
]
}
})
* {
font-family: Arial;
font-size: 10px;
}
div {
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.5/js/select2.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.5/css/select2.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="app">
<bs-select v-model="test" :options="options"></bs-select>
<br><br>
<button @click="test = 'bug'">
Set 'test' variable to 'bug' (Two-way check)
</button>
{{ test }}
</div>
<div>
Event is firing twice in console...
</div>
我也用Google搜索了很多,但仍未得出关于为什么发生这种情况和/或如何解决此问题的结论。
非常感谢您的帮助。
答案 0 :(得分:0)
我不确定您在这里到底想做什么,但是我猜您是两次触发onchange事件,一次是在实际更改时,一次是在观察程序中触发。无论如何,当有可用的vue解决方案时,您实际上并不需要像这样使用侦听器:
grid.draw(12, [&]{a.draw()});
组件:
<div id="app">
<bs-select :value="test" v-on:change-value="test = $event" :options="options"></bs-select>
<br><br>
{{ test }}
<br><br>
<button @click="test = 'bug'">
Set 'test' variable to 'bug'
</button>
</div>
<div>
Event is firing twice in console...
</div>
答案 1 :(得分:0)
问了我的一些朋友后,一个人发现“更改”触发器必须位于beforeUpdate
中。
因此,已解决的代码如下:
Vue.component("bs-select",{
template:
`<div class="form-group">
<label class="control-label">{{ label }}</label>
<select2
ref="select2control"
:options="options"
:value="value"
@input="chosenOption"
></select2>
</div>`,
props: ["value", "label", "options"],
methods: {
chosenOption(val) {
this.$emit("input", val);
}
}
});
Vue.component("select2",{
template:
`<select :value="value" style="width: 100%">
<option value="" selected disabled>Choose...</option>
<option v-if="!options">{{ value }}</option>
<option v-for="option in options" :value="option.value">{{ option.text }}</option>
</select>`,
props: ["value", "options"],
mounted: function() {
const vm = this;
$(vm.$el)
.select2()
.on("change", function() {
console.log("CHANGE", vm.$el.value);
vm.$emit("input", vm.$el.value);
});
},
beforeUpdate() {
$(this.$el).val(this.value).trigger('change.select2')
}
});
new Vue({
el: "#app",
data: {
test: "hello",
options: [
{
value: "hello",
text: "Hello"
},
{
value: "solved",
text: "Solved"
}
]
}
})
* {
font-family: Arial;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.5/js/select2.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.5/css/select2.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script></script>
<div id="app">
<bs-select v-model="test" :options="options"></bs-select>
<br><br>
{{ test }}
<br><br>
<button @click="test = 'solved'">
Set 'test' variable to 'solved'
</button>
</div>
效果很好,但他还建议我使用this approach,它更干净。我现在正在使用它,但是如果有人需要,我也会保留该问题的原始答案。
答案 2 :(得分:0)
对于现在遇到这种情况的任何人,这是使它仅发射一次的正确方法。
<template>
<select><slot></slot></select>
</template>
<script>
module.exports = {
props: ['options', 'value'],
mounted: function () {
console.log(this.options);
var vm = this;
$(this.$el)
// init select2
.select2({
data: this.options,
theme: 'bootstrap',
width: '100%',
placeholder: 'Select',
allowClear: true
})
.val(this.value)
.trigger('change')
// emit event on change.
.on('select2:select', function () { // bind to `select2:select` event
vm.$emit('input', this.value)
});
},
watch: {
value: function (value) {
// update value
$(this.$el)
.val(value)
.trigger('change');
},
options: function (options) {
// update options
$(this.$el).empty().select2({ data: options })
}
},
destroyed: function () {
$(this.$el).off().select2('destroy')
}
}
</script>