You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;">&times;</span>
    </li>
    <li class="badge badge-pill badge-danger" @click="uncheckall" v-show="checkedNames.length">Clear</li>
  </ul>
</div>

内容的提问来源于stack exchange,提问作者T dhanunjay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.21 00:36:07