选框和文字分开点击,找了很多,没有我想要的效果,但也借鉴了一下,实现了,记录一下
样式看起来倒是没多大区别,需求:
- 勾选了选框才可以点击文字 ,一次只能点击一条数据,点击文字,此条数据可以向上或向下移动,且此条数据的背景需高亮,就像这样:
- 排序只在勾选的数据中有效,取消勾选,背景取消高亮
解决点击文字,不影响选中状态:
我在网上搜到的是首先要写一个span标签将数据包裹起来,添加点击事件,一定要加上 .prevent.stop
<el-checkbox-group v-model="selectedItems"><div v-for="(item, index) in vmList" :key="item.name" class="checkbox-item":class="{ 'highlight': isHighlighted(item)}"><el-checkbox :label="item.name" @change="handleCheckboxClick"><span @click.prevent.stop="isSelected(item) ? handleNameClick(item) : null" :class="{ 'disabled': isSelected(item) }" class="custom-span">{{item.name }}</span></el-checkbox></div>
</el-checkbox-group><div class="arrow-column"><el-button type="primary" icon="el-icon-arrow-up" @click="moveUp" :disabled="isMoveUpDisabled"></el-button><el-button type="primary" icon="el-icon-arrow-down" @click="moveDown" :disabled="isMoveDownDisabled"></el-button>
</div>
这样才可以实现点击文字不影响选中状态。就可以实现点击文字切换背景了,但其实我要的是点击背景,也可以选择整条数据并且背景高亮。
el-checkbox内部原本就有一个span标签,类名为 .el-checkbox__label,这个标签包裹在我加的span标签外面,不管怎么调整,文字周围都有一圈背景被点击后还是会改变选中状态。
后面我给.el-checkbox__label设置了一下,让文字大小和行高一致,再设置padding为0,这样点击文字及其背景就不会影响选中状态了。但是每条数据之间没有间距,看起来很拥挤,就像这样:
所以只能在我自己写的span标签想办法了,这样设置了一下 ,就正常了:
.custom-span {display: block;min-height: 16px;min-width: 160px;padding: 10px 0 10px 10px;
}
以下是全部代码:
computed计算向上或向下按钮是否可用:
computed: {// 根据选中的项计算向上移动按钮是否可用isMoveUpDisabled() {const firstSelectedItemIndex = this.vmList.findIndex( item => {if(this.highlightedItem && this.highlightedItem.name==item.name){return item}})// 如果没有选中项或选中项在第一项则禁用return firstSelectedItemIndex === -1 || firstSelectedItemIndex === 0; },// 根据选中的项计算向下移动按钮是否可用isMoveDownDisabled() {const lastHighlightedIndex = this.vmList.findIndex( item => { if(this.highlightedItem & this.highlightedItem.name==item.name){return item}}, this.vmList.length - 1);// 如果没有高亮项或高亮项在最后一项则禁用return lastHighlightedIndex === -1 || lastHighlightedIndex === this.vmList.length - 1; }
},
向上向下移动并给勾选后的数据,添加order
// 向上移动选中的项
moveUp() {this.deviceList = []const selectedIndices = this.vmList.findIndex(vm => vm.name == this.selectedVms.name)if (selectedIndices > 0) {const vmToMove = this.vmList[selectedIndices]this.vmList.splice(selectedIndices, 1)this.vmList.splice(selectedIndices - 1, 0, vmToMove)}this.handleOrder()
},// 向下移动选中的项
moveDown() {this.deviceList = []const selectedIndices = this.vmList.findIndex(vm => vm.name == this.selectedVms.name)if (selectedIndices < this.vmList.length - 1) {const vmToMove = this.vmList[selectedIndices]this.vmList.splice(selectedIndices, 1)this.vmList.splice(selectedIndices + 1, 0, vmToMove)}this.handleOrder()
},// 添加order
handleOrder(){const deviceListCopy = JSON.parse(JSON.stringify(this.vmList));this.deviceList=[...deviceListCopy]let orderCount = 1;for(let i=0;i<this.deviceList.length;i++){const item = this.deviceList[i];// 检查当前项是否在 selectedItems 中if (this.selectedItems.includes(item.name)){// 如果存在,则添加 order 属性item.order = String(orderCount);orderCount++;}else{delete item.order;}}
}
点击勾选和文字
handleCheckboxClick(item) {// 取消勾选if (!item) {// 取消高亮this.highlightedItem = null}this.handleOrder()
},highlightItem(item) {// 点击整个项时,只改变背景颜色this.highlightedItem = (this.highlightedItem === item) ? null : item;
}, isHighlighted(item) {return this.highlightedItem === item;
}, //判断是否勾选,也就是文字是否可以点击
isSelected(item) {return this.selectedItems.includes(item.name);
}, // 点击文字
handleNameClick(item){this.selectedVms = itemthis.highlightItem(item); // 触发高亮效果
}
样式如下:
.vm-container {float: left;border: 2px solid #dcdfe6;min-width: 200px;max-width: 300px;min-height: 250px;max-height: 300px;overflow-x: auto;overflow-y: auto;
}.el-checkbox-group{align-items: left;.el-checkbox{margin-right: 0px;}
}line-height: 0px;.vm-container:after {content: "";display: table;clear: both;
}::v-deep .el-checkbox .el-checkbox__inner{width: 15px;height: 15px;
}.vm-container::v-deep .el-checkbox {color: #9c9ea0;
}::v-deep .el-checkbox .el-checkbox__input.is-checked .el-checkbox__inner::after {top: 2px;left: 5px;
}.arrow-column {margin-left: 10px;float: left;display: flex;flex-direction: column;align-items: left;justify-content: center;
}.el-button+.el-button {margin-left: 0px;margin-top: 5px;
}.vm-container::v-deep .el-checkbox__label {font-size: 16px;line-height: 16px;padding-left: 0px;
}.vm-container::v-deep .el-checkbox__input.is-checked+.el-checkbox__label {color: #333333;
}.transfer-footer {margin-left: 20px;padding: 6px 5px;
}.vm-container::v-deep .checkbox-item {display: flex;align-items: center;cursor: pointer;padding: 0 0 0 10px;position: relative;
}.vm-container::v-deep .checkbox-item.highlight {background-color: #a9d9e9 !important; /* 改变背景色 */
}.vm-container::v-deep .checkbox-item.highlight span {color: white !important; /* 确保文本颜色为白色 */
}.custom-span {display: block;min-height: 16px;min-width: 160px;padding: 10px 0 10px 10px;
}
🆗🦌