Vue.js不使用v-model通过@click实现复选框选中后状态同步异常问题
核心问题分析
- 复选框未与选中数组做状态绑定:没有给
<input type="checkbox">绑定:checked属性,修改checkedNames数组时无法同步更新复选框的选中状态,是两个报错问题的核心诱因 - 事件类型选择错误:使用
@click触发逻辑,浏览器原生会先切换复选框的选中状态再触发事件,当数组和复选框状态不一致时(比如点击Clear清空数组后,复选框仍为选中状态),判断逻辑会完全反向 - 全局关闭标识冲突:所有选中标签共用同一个
close变量,hover任意标签会导致所有标签都显示关闭叉号 - 标签删除触发范围不合理:点击整个标签都会触发删除逻辑,不符合常规交互习惯
修复后完整代码
修复方案完全遵循不使用v-model的要求,仅通过手动绑定:checked和@change事件实现状态同步。
JavaScript代码
new Vue({ el: '#app', data: { checkedNames: [], // 移除无用的checkedName变量,修改为存储当前hover的标签值,避免全局冲突 hoverCloseTag: '' }, methods: { uncheck: function(checkedName) { this.checkedNames = this.checkedNames.filter(name => name !== checkedName); }, uncheckall: function() { this.checkedNames = []; }, mouseOver: function(tagName) { this.hoverCloseTag = tagName; }, mouseOut: function() { this.hoverCloseTag = ''; }, checkedInput(event) { const value = event.target.value const isChecked = event.target.checked if (isChecked) { !this.checkedNames.includes(value) && this.checkedNames.push(value) } else { this.uncheck(value) } } } })
HTML代码
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" /> <div id='app'> <ul class="checkboxes"> <li> <input type="checkbox" id="jack" value="Jack" :checked="checkedNames.includes('Jack')" @change="checkedInput"> <label for="jack">Jack</label> </li> <li> <input type="checkbox" id="john" value="John" :checked="checkedNames.includes('John')" @change="checkedInput"> <label for="john">John</label> </li> <li> <input type="checkbox" id="mike" value="Mike" :checked="checkedNames.includes('Mike')" @change="checkedInput"> <label for="mike">Mike</label> </li> </ul> <br/> <ul class="tags"> <li class="badge badge-pill badge-primary" v-for="checkedName in checkedNames" @mouseover="mouseOver(checkedName)" @mouseleave="mouseOut"> {{ checkedName }} <span v-show="hoverCloseTag === checkedName" aria-hidden="true" @click="uncheck(checkedName)" style="margin-left: 4px;cursor: pointer;">×</span> </li> <li class="badge badge-pill badge-danger" @click="uncheckall" v-show="checkedNames.length">Clear</li> </ul> </div>
内容的提问来源于stack exchange,提问作者T dhanunjay
相关产品推荐
相关产品推荐

