我有一个@click
绑定到v-for
循环中的单个项目。在生成的渲染中,每个项目都应该有一个@click
,所以单击一个项目应该触发绑定到该项目的函数一次。
但它触发的次数和物品一样多。为什么?
<ul>
<li :key="option.value" v-for="option in options">
<QuizCheckbox
@click.native="handleClick(option.value)"
>
{{ option.value }}
</QuizCheckbox>
</li>
</ul>
...
methods: {
handleClick(val) {
console.log(val);
},
编辑:如果我换了…使用一个简单的元素,那么单击它不会触发问题。所以<QuizCheckbox>
组件才是罪魁祸首。然而,其中似乎没有任何东西表明是什么导致了这个问题。下面是QuizCheckbox.vue
的内容:
<template>
<div :class="['quiz-checkbox', {'quiz-checkbox--checked': shouldBeChecked}]">
<div :class="['form-checkbox']">
<label class="form-checkbox__label">
<slot/>
<input
:checked="shouldBeChecked"
:value="value"
@change="updateInput"
class="form-checkbox__input"
type="checkbox"
/>
<span class="form-checkbox__checkmark"></span>
</label>
</div>
</div>
</template>
<script>
export default {
model: {
prop: 'modelValue',
event: 'change'
},
props: {
value: {
type: String,
},
modelValue: {
type: [Boolean, Array],
default: false
}
},
computed: {
shouldBeChecked() {
if (this.modelValue instanceof Array) {
return this.modelValue.includes(this.value);
}
return this.modelValue;
}
},
created() {
if (!this.$slots.default) {
console.error('QuizCheckbox: requires label to be provided in the slot');
}
},
methods: {
updateInput(event) {
const isChecked = event.target.checked;
if (this.modelValue instanceof Array) {
const newValue = [...this.modelValue];
if (isChecked) {
newValue.push(this.value);
} else {
newValue.splice(newValue.indexOf(this.value), 1);
}
this.$emit('change', newValue);
} else {
this.$emit('change', isChecked);
}
}
}
};
</script>
2条答案
按热度按时间dy2hfwbg1#
你发布的代码看起来很好。虽然这里简化了你发布运行的代码:
问题一定出在别处。
dgtucam12#
触发的第二个点击事件的罪魁祸首是
QuizCheckbox
label
元素及其与最外面的div
的关系。你实际上有两个点击监听器。你在最外面的
div
元素上赋值的一个,第二个是JS在input
元素上赋值的。后者也可以通过点击label
元素来触发。您不能单独单击外部
div
(您期望发生的事情)和内部label
(如果您精确单击它)。单击label
会产生要冒泡的click事件(参见捕获和冒泡JS事件的phases)。您可以通过在
label
或input
元素上使用v-on:click.stop
来避免第二个触发。或者,您可以在
handleClick($event, option.value)
处理程序中管理事件(请参阅作为第一个参数传递的$event
),并根据例如:event.target
:这可以是label
或外部div
元件。