Vue3中如何在v-for循环内为选中项单独动态绑定class
解决方案
你现在的问题本质是把选中状态做成了所有行共享的全局布尔值,只要这个值为true,所有循环项的类名判断条件都会成立,自然会全部应用样式。完全不需要操作原生DOM,用Vue的数据驱动逻辑就能实现,步骤如下:
- 替换响应式状态
删掉原来的布尔值isSelected,改为存储当前选中行唯一ID的响应式变量,默认无选中时设为null即可:import { ref } from 'vue' const lignes = ref(/* 你的原始数组数据 */) // 替换原来的isSelected const selectedId = ref(null) - 调整点击事件逻辑
点击行时直接把当前行的id赋值给选中状态即可,不需要做任何DOM操作:const select = (id) => { selectedId.value = id // 如果要支持点击同一行取消选中,用下面这行替换上面的赋值逻辑 // selectedId.value = selectedId.value === id ? null : id } - 修改模板的类名绑定
类名判断条件改为「当前循环行的id === 存储的选中id」,这样只有匹配的行才会加上border-b-2类,你之前手动绑定的id属性也可以删掉了:<div v-for="ligne in lignes" :key="ligne.id" :class="{ 'border-b-2': ligne.id === selectedId }" > <span @click="select(ligne.id)">X</span> </div>
扩展:多选场景实现
如果需要支持同时选中多行,把存储选中ID的变量改成数组类型即可:
// 多选状态 const selectedIds = ref([]) const select = (id) => { const idx = selectedIds.value.indexOf(id) if (idx > -1) { // 已选中则移除 selectedIds.value.splice(idx, 1) } else { // 未选中则加入 selectedIds.value.push(id) } }
模板对应的类名判断同步修改:
:class="{ 'border-b-2': selectedIds.includes(ligne.id) }"
不要在Vue项目里优先用原生DOM操作修改样式/属性,这种方式绕开了Vue的响应式更新机制,很容易出现数据和视图不同步的bug,也增加了不必要的代码量。
内容的提问来源于stack exchange,提问作者thiebo
相关产品推荐
相关产品推荐

