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

Vue.js列表类切换异常:Bug还是框架限制?

问题根源:Vue数组响应式检测的局限性

这个问题的核心是Vue无法检测到通过直接索引赋值添加的数组元素的响应式变化,咱们一步步拆解:

为什么会出现这个问题?

Vue的响应式系统对数组的监听,是通过重写数组的push/pop/splice等7个方法实现的——只有调用这些方法修改数组时,Vue才能感知到变化并更新视图。

而你初始化二维数组时用了这样的代码:

this.timeblocks = [];
for (var i = 1; i < 8; i++) {
  this.timeblocks[i] = []; // 直接通过索引给数组赋值
  // ... 向子数组添加元素
}

这里直接给timeblocks的索引i赋值了一个新数组,Vue并没有把这个新的子数组转化为响应式对象。所以当你修改timeblocks[1]里的obj.val时,Vue根本感知不到这个变化,自然不会更新对应的active类样式。

至于你用nextTick能临时生效,是因为nextTick会等待下一次DOM更新周期,但这只是绕开了问题,并没有从根源解决响应式的问题。

彻底解决的方案

方案1:初始化时用响应式方法添加子数组

不要直接通过索引赋值,而是用push来添加子数组,让Vue自动把它们变成响应式的:

this.timeblocks = [];
for (var i = 1; i < 8; i++) {
  // 先创建子数组,再push到父数组中
  const subBlock = [];
  this.timeblocks.push(subBlock);

  // 向子数组添加AM时段的块
  for (var j = 1; j < 25; j++) {
    const id = `iam${i}_${j}`;
    subBlock.push({
      id,
      val: false,
      zone: 'mid',
      time: `${this.getTime(j)} AM`
    });
  }

  // 添加PM时段的块
  for (var j = 1; j < 25; j++) {
    const id = `ipm${i}_${j}`;
    subBlock.push({
      id,
      val: false,
      zone: 'noon',
      time: `${this.getTime(j)} PM`
    });
  }
}

方案2:用$set手动触发响应式

如果一定要保留索引赋值的写法,可以用Vue提供的$set方法(全局的Vue.set也可以),手动告诉Vue这个位置的数组元素发生了变化:

this.timeblocks = [];
for (var i = 1; i < 8; i++) {
  const subBlock = [];
  // 用$set把新数组设置到指定索引,让Vue感知到变化
  this.$set(this.timeblocks, i, subBlock);

  // 后续添加元素的代码和之前一致
  for (var j = 1; j < 25; j++) {
    const id = `iam${i}_${j}`;
    subBlock.push({
      id,
      val: false,
      zone: 'mid',
      time: `${this.getTime(j)} AM`
    });
  }
  for (var j = 1; j < 25; j++) {
    const id = `ipm${i}_${j}`;
    subBlock.push({
      id,
      val: false,
      zone: 'noon',
      time: `${this.getTime(j)} PM`
    });
  }
}

验证效果

修改完初始化代码后,你就可以直接在点击事件里切换obj.val了:

<a class="mid" 
   :id="obj.id" 
   v-for="(obj, index) in timeblocks[1]" 
   :data-value="obj.time" 
   :class="{'active':obj.val}" 
   @click="obj.val = !obj.val">
  {{obj.id}}
</a>

这时候active类会随着obj.val的变化正常切换,完全不需要依赖jQuery的toggleClass了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:55:28