青春有我
我想出了一个解决你的问题的方法。我添加了一个模拟对象来重新创建相同的场景,希望您有一个对象数组。已编辑:已修改解决方案以满足多个取消选择的场景new Vue({ el: '#app', data: { paginatedData: [ {"link":"https://img.icons8.com/list","idfile":296,"idaccess":2}, {"link":"https://img.icons8.com/list","idfile":6,"idaccess":99}, {"link":"https://img.icons8.com/list","idfile":26,"idaccess":29}, {"link":"https://img.icons8.com/list","idfile":960,"idaccess":2919}, {"link":"https://img.icons8.com/list","idfile":16,"idaccess":9339}, {"link":"https://img.icons8.com/list","idfile":2,"idaccess":9}, ], lastCheckedIdx: -1, checkedFilesPermission : [] }, methods: { onClickWithShift(event, idx, idFile) { var action = (this.checkedFilesPermission.indexOf(idFile) === -1) ? 'select' : 'deselect'; if (event.shiftKey && this.lastCheckedIdx !== -1) { var start = this.lastCheckedIdx; var end = idx-1; // can select top to bottom or bottom to top // always start with lesser value if (start > end) { start = idx+1; end = this.lastCheckedIdx; } for (var c = start; c <= end; c++) { var currentIdFile = this.paginatedData[c]['idfile']; this.markSelectDeselect(c, action, currentIdFile); } } this.markSelectDeselect(idx, action, idFile); this.lastCheckedIdx = idx; if (this.checkedFilesPermission.length === 0) { //reset last checked if nothing selected this.lastCheckedIdx = -1; } }, markSelectDeselect(idx, action, idFile) { var currentPos = this.checkedFilesPermission.indexOf(idFile); if (action === 'select' && currentPos === -1) { this.checkedFilesPermission.push(idFile); } else if (action === 'deselect' && currentPos !== -1){ this.checkedFilesPermission.splice(currentPos, 1); } } }})<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script><div id="app"> <div class="data__file" v-for="(data, index) in paginatedData" :key="index" > <input :id="data.idfile" type="checkbox" class="data__access" :value="data.idfile" v-model="checkedFilesPermission" /> <label class="data__info" :for="data.idfile" @click="onClickWithShift($event, index, data.idfile)"> <img :src="data.link" alt="" :class= "{ 'data__image' : 1 ,'data__image-active' : (checkedFilesPermission.indexOf(data.idfile) !== -1) }" /> </label> </div></div>您需要单击图像图标才能看到结果,因为您已经提到输入是隐藏的。我在这里保持它可见,以便您可以看到它实际上正在发生变化
大话西游666
这是我刚刚尝试过的似乎可以完成工作的东西<template> <div> <div v-for="(item, index) in items" :key="index"> <label> <input type="checkbox" v-model="item.checked" @click="checked($event, index)"> {{item.file}} </label> </div> <pre>{{items}}</pre> </div></template><script>export default { data() { return { lastCheckedIndex: null, lastChange: null, items: [ { file: "foo1", idx: 10 }, { file: "foo2", idx: 20 }, { file: "foo3", idx: 40 }, { file: "foo4", idx: 30 }, { file: "foo5", idx: 10 }, { file: "foo6", idx: 90 }, { file: "foo8", idx: 50 }, ] } }, methods: { checked(event, index) { // wheter or not to the multiple selection if (event.shiftKey && (null != this.lastCheckedIndex) && (this.lastCheckedIndex != index)) { const dir = index > this.lastCheckedIndex ? 1 : -1; // going up or down ? const check = this.lastChange; // are we checking all or unchecking all ? for (let i = this.lastCheckedIndex; i != index; i += dir) { this.items[i].checked = check; } } // save action this.lastCheckedIndex = index; this.lastChange = !this.items[index].checked; // onclick is triggered before the default change hence the ! } },};</script>