如何使父标签和子标签在不重复 b-form-checkbox 的情况下具有 onclick
How to make parent tag and child tag have onclick without repetition on a b-form-checkbox
我有一个带有一些不同子标签的 li 标签,其中还包括一个 b-form-checkbox。我希望当我单击 li
标记上的任意位置时复选框起作用,并且还包含在复选框中。
当我点击 li
中的任何地方时,它工作正常,但是当我点击 b-form-checkbox
时,onclick
事件被调用 2 次,复选框只需点击 1 次即可选中和取消选中。我已经尝试了很多方法,比如 .self
但是 v-on:click
在 b-form-checkbox
上不起作用。
li
下面的标签代码包括它们所在的 b-form-checkbox
和 template
标签。
<template v-for="(product, index) in products">
<div
class="col-12 col-md-6"
:key="product.id"
v-if="!product.responded"
>
<li
class="products-search__list-item"
v-on:click.self="toggleProduct(index)"
>
<div v-on:click.self="toggleProduct(index)" class="products-search__image">
<img :src="product.img" alt="product.id" />
</div>
<div v-on:click.self="toggleProduct(index)" class="products-search__details">
<span>{{ product.amount }}x {{ product.name }}</span>
<span v-if="$func.regionCheckGLobal()"
>$ {{ product.unitPrice }} / unit</span
>
<span v-else>PKR {{ product.unitPrice }} / unit</span>
</div>
<div v-on:click.self="toggleProduct(index)" class="products-search__check-box" >
<b-form-checkbox v-on:click.self="toggleProduct(index)" v-model="product.checked" > </b-form-checkbox>
</div>
</li>
</div>
</template>
data()
在下面的脚本部分相关变量
return {
products: [],
};
methods:
vue 相关脚本部分的代码 onclick
toggleProduct(index) {
this.products[index].checked = !this.products[index].checked;
}
<template>
<div class="container">
<div v-for="(product, index) in products" :key="index">
<div class="col-12 col-md-6" :key="product.id" v-if="!product.responded">
<li class="products-search__list-item" @click="toggleProduct(index)">
<div class="products-search__image">
<img :src="product.img" alt="product.id" />
</div>
<div class="products-search__details">
<span>{{ product.amount }}x {{ product.name }}</span>
<span>$ {{ product.unitPrice }} / unit</span>
</div>
<div class="products-search__check-box">
<b-form-checkbox v-model="product.checked" />
</div>
</li>
</div>
</div>
</div>
</template>
这就是我修改模板的方式,您可以使用 b-form-checkbox 而不是输入类型复选框,它的行为方式应与我示例中的输入方式相同。
这是我为使其工作所做的 Code Sandbox link,我相信这就是您所需要的,现在我将更详细地解释:
因为您在 li
的所有子组件上都有所有这些 click
侦听器,所以您点击有点击侦听器的区域,例如 checkbox
和div
checkbox
和 div
div with checkbox 在点击事件中冒泡到最外层的组件,在这种情况下,您可以放置一个点击监听器在最外面的组件上,您希望通过我们希望触发点击的每个子组件(请不要嵌套处理程序)触发操作。
总而言之,不要做嵌套的事件侦听器!
希望对您有所帮助!
更新:再次检查您的代码以了解我的代码与您的代码之间的差异,为您添加了 bootstrap-vue
,并在 codesandbox example 中使用了 b-form-checkbox
!这可以按照您的意愿工作:D
上面的答案也是正确的,但在我的情况下并不完美,可能是因为我使用 bootstrap 插件的方式存在一些问题,但无论如何。
我在存在 b-form-checkbox
的直接父 div 上使用了 v-on:click.stop.prevent="toggleProduct(index)"
并删除了所有 click
事件侦听器,除了 li
和 checkbox
并且它有效对我来说。
li on click listener 如下所示。
<li class="products-search__list-item"
v-on:click="toggleProduct(index)
>
b-form-checkbox点击监听如下图
<div v-on:click.stop.prevent="toggleProduct(index)" class="products-search__check-box" >
<b-form-checkbox v-model="product.checked" > </b-form-checkbox>
</div>
我有一个带有一些不同子标签的 li 标签,其中还包括一个 b-form-checkbox。我希望当我单击 li
标记上的任意位置时复选框起作用,并且还包含在复选框中。
当我点击 li
中的任何地方时,它工作正常,但是当我点击 b-form-checkbox
时,onclick
事件被调用 2 次,复选框只需点击 1 次即可选中和取消选中。我已经尝试了很多方法,比如 .self
但是 v-on:click
在 b-form-checkbox
上不起作用。
li
下面的标签代码包括它们所在的 b-form-checkbox
和 template
标签。
<template v-for="(product, index) in products">
<div
class="col-12 col-md-6"
:key="product.id"
v-if="!product.responded"
>
<li
class="products-search__list-item"
v-on:click.self="toggleProduct(index)"
>
<div v-on:click.self="toggleProduct(index)" class="products-search__image">
<img :src="product.img" alt="product.id" />
</div>
<div v-on:click.self="toggleProduct(index)" class="products-search__details">
<span>{{ product.amount }}x {{ product.name }}</span>
<span v-if="$func.regionCheckGLobal()"
>$ {{ product.unitPrice }} / unit</span
>
<span v-else>PKR {{ product.unitPrice }} / unit</span>
</div>
<div v-on:click.self="toggleProduct(index)" class="products-search__check-box" >
<b-form-checkbox v-on:click.self="toggleProduct(index)" v-model="product.checked" > </b-form-checkbox>
</div>
</li>
</div>
</template>
data()
在下面的脚本部分相关变量
return {
products: [],
};
methods:
vue 相关脚本部分的代码 onclick
toggleProduct(index) {
this.products[index].checked = !this.products[index].checked;
}
<template>
<div class="container">
<div v-for="(product, index) in products" :key="index">
<div class="col-12 col-md-6" :key="product.id" v-if="!product.responded">
<li class="products-search__list-item" @click="toggleProduct(index)">
<div class="products-search__image">
<img :src="product.img" alt="product.id" />
</div>
<div class="products-search__details">
<span>{{ product.amount }}x {{ product.name }}</span>
<span>$ {{ product.unitPrice }} / unit</span>
</div>
<div class="products-search__check-box">
<b-form-checkbox v-model="product.checked" />
</div>
</li>
</div>
</div>
</div>
</template>
这就是我修改模板的方式,您可以使用 b-form-checkbox 而不是输入类型复选框,它的行为方式应与我示例中的输入方式相同。 这是我为使其工作所做的 Code Sandbox link,我相信这就是您所需要的,现在我将更详细地解释:
因为您在 li
的所有子组件上都有所有这些 click
侦听器,所以您点击有点击侦听器的区域,例如 checkbox
和div
checkbox
和 div
div with checkbox 在点击事件中冒泡到最外层的组件,在这种情况下,您可以放置一个点击监听器在最外面的组件上,您希望通过我们希望触发点击的每个子组件(请不要嵌套处理程序)触发操作。
总而言之,不要做嵌套的事件侦听器!
希望对您有所帮助!
更新:再次检查您的代码以了解我的代码与您的代码之间的差异,为您添加了 bootstrap-vue
,并在 codesandbox example 中使用了 b-form-checkbox
!这可以按照您的意愿工作:D
上面的答案也是正确的,但在我的情况下并不完美,可能是因为我使用 bootstrap 插件的方式存在一些问题,但无论如何。
我在存在 b-form-checkbox
的直接父 div 上使用了 v-on:click.stop.prevent="toggleProduct(index)"
并删除了所有 click
事件侦听器,除了 li
和 checkbox
并且它有效对我来说。
li on click listener 如下所示。
<li class="products-search__list-item"
v-on:click="toggleProduct(index)
>
b-form-checkbox点击监听如下图
<div v-on:click.stop.prevent="toggleProduct(index)" class="products-search__check-box" >
<b-form-checkbox v-model="product.checked" > </b-form-checkbox>
</div>