Vue.js+Vuetify中点击toggle-switch时事件触发两次问题排查
事件重复触发的原因及解决方案
原因分析
点击toggle-switch区域时函数被触发两次,核心原因是Vuetify的v-switch组件内部DOM结构包含<label>和<input type="checkbox">:
- 点击switch时,浏览器会先触发
<label>的click事件,随后<input>的click事件也会被触发(因为点击label会自动触发关联input的点击); - 这两个
click事件都会向上冒泡到父级的v-card,导致绑定的goToTicketDetails函数被执行两次,进而触发两次updateTicketStatus。
解决方案
推荐用阻止事件冒泡的方式拆分逻辑,避免事件穿透:
方法一:给toggle-switch容器绑定独立事件并阻止冒泡
修改HTML代码,让toggle-switch容器单独处理点击逻辑,同时阻止事件冒泡到v-card:
<v-card class="text-left ticket-card" @click="goToTicketDetails($event, ticket)" > Some content <div class="toggle-switch" @click.stop="!ticket.isReadOnly && updateTicketStatus(ticket)"> <v-switch v-model="ticket.isOpen" hide-details class="status-switch" :readonly="ticket.isReadOnly" ></v-switch> <p class="status-text"> {{ ticket.isOpen ? "Active" : "Resolved" }} </p> </div> </v-card>
同时简化goToTicketDetails函数,移除toggle-switch的判断逻辑:
function goToTicketDetails(e, ticket) { // 直接执行跳转页面的逻辑 // some code }
方法二:给v-switch单独绑定事件并阻止冒泡
如果只需要点击switch控件时触发状态更新,可以直接给v-switch添加阻止冒泡的点击事件:
<v-switch v-model="ticket.isOpen" hide-details class="status-switch" :readonly="ticket.isReadOnly" @click.stop="!ticket.isReadOnly && updateTicketStatus(ticket)" ></v-switch>
同样需要简化goToTicketDetails函数,专注处理卡片跳转逻辑。
内容的提问来源于stack exchange,提问作者Poovizhi
相关产品推荐
相关产品推荐

