Vue.js中v-for循环内如何定位点击事件对应的目标待办项
解决方案
1. 定位触发点击事件的对应待办项
你可以直接在事件绑定时,将当前循环的todo对象作为参数传入处理函数,这是Vue列表循环中处理元素事件的标准方案:
<!-- 模板部分修改事件绑定 --> <div class="todo__actions"> <i @click="editTodo(todo)" class="icofont-edit"></i> <i @click="moveRight(todo)" class="icofont-arrow-right"></i> <i @click="moveLeft(todo)" class="icofont-arrow-left"></i> </div>
之后在对应的methods中直接接收这个参数即可操作对应的待办对象,不需要通过DOM反向查找数据:
methods: { moveRight(todo) { // 直接操作传入的todo对象即可 if(todo.status < 2) { // 假设status取值:0=待办 1=进行中 2=已完成 todo.status += 1 } }, moveLeft(todo) { if(todo.status > 0) { todo.status -= 1 } }, editTodo(todo) { // 编辑逻辑直接使用todo对象 } }
2. 优化列表实现、解决linter警告
你的判断是对的,linter禁止的是同一元素上同时使用v-for和v-if,直接在v-for的同层元素写过滤逻辑会被判定为不规范,同时手动维护三个数组也会增加额外的逻辑成本,最优方案是用计算属性来生成三个状态的待办列表:
- 首先在data中只维护一个总待办数组
allTodos,存储所有状态的待办对象 - 通过计算属性自动过滤出三个状态的列表,计算属性自带缓存,只有总数组变更时才会重新计算,性能优于手动维护:
computed: { todoTodos() { return this.allTodos.filter(todo => todo.status === 0) }, doingTodos() { return this.allTodos.filter(todo => todo.status === 1) }, doneTodos() { return this.allTodos.filter(todo => todo.status === 2) } }
这个方案完全避免了同层v-for和v-if的使用,同时你修改待办的status属性后,计算属性会自动更新三个列表,UI会自动刷新,不需要手动操作数组增删。
额外注意事项
如果你使用的是Vue2,需要确保所有待办对象初始化时就已经声明了status属性,否则修改status时不会触发响应式更新,如果是后续添加的status属性,需要用this.$set(todo, 'status', 新值)来保证响应性。
内容的提问来源于stack exchange,提问作者Gradient
相关产品推荐
相关产品推荐

