前端element-plus实现表格点击某一行选中,按ctrl点击行多选,按shift点击行连选
1.实现效果
2.代码
框架vue3,组件库element-plus
我在这里使用el-table二次封装了一个表格组件
<template><div :class="`ycd-table ${props.class}`"><el-table
ref="tableRef":data="props.data"
style="width: 100%"class="ycd-table":header-cell-style="{backgroundColor:'#f5f7fa',}"
border
row-key="id":highlight-current-row="highlightCurrentRow":row-class-name="tableRowClassName"
@row-click="handleRowClick"
@selection-change="handleSelectionChange"
@current-change="handleCurrentChange":height="props.height"
table-layout="auto"><el-table-column
fixed="left"
type="selection"
width="38":reserve-selection="true"
v-if="type === 1":selectable="selectableFn"/><slot></slot><template #empty><el-empty description="暂无数据"/></template></el-table></div></template><script setup>import{ nextTick, ref, watch }from"vue";const props =defineProps({type:{type: Number,default:0,// 0: 普通表格 1: 多选表格},data:{type: Array,default:[],},class:{type: String,default:"",},height:{type: String,default:"600",},// 高亮当前行,单选时使用highlightCurrentRow:{type: Boolean,default:false,},// 默认勾选selected:{type: Array,default:[],},// 自定义选择是否禁用selectableFn:{type: Function,default:()=>true,},// 选中的行multipleSelection:{type: Array,default:[],},// 显示时用于清空选择show:{type: Boolean,default:false,},});const emits =defineEmits(["row-click","selection-change","current-change","update:multipleSelection",]);const tableRef =ref();// 定义选中行的classconsttableRowClassName=({ row, rowIndex })=>{if(props.multipleSelection.some((item)=> item?.id === row?.id)){return"table-selected-row";}return"";};// *****************主要功能代码***************// 上一次点击的索引const lastClickIndex =ref(undefined);// 上一次选择的方式 1:单选,2:多选,3:连选let lastSelectStatus =1;// 表格行点击事件consthandleRowClick=(row, column, e)=>{// 测试自定义禁用规则,如果这一行通过规则校验为false,说明这一行是禁止选择的,不进行勾选if(!props.selectableFn(row)){return;}const{ ctrlKey, shiftKey }= e;const rowIndex = props.data.findIndex((item)=> item.id === row.id);if(!ctrlKey &&!shiftKey){// ctrl和shift都没有按下时单选// 如果上次的索引和这次的索引不同 或 上一次不是单选 则清空选择if(lastClickIndex.value !== rowIndex || lastSelectStatus !==1){
tableRef.value.clearSelection();}
tableRef.value.toggleRowSelection(row,undefined);
lastSelectStatus =1;}elseif(ctrlKey){// 按下ctrl多选
tableRef.value.toggleRowSelection(row,undefined);
lastSelectStatus =2;}elseif(shiftKey){// 按下shift连选if(lastClickIndex.value ===undefined){return;}let minIndex =0;let maxIndex =0;if(rowIndex < lastClickIndex.value){
minIndex = rowIndex;
maxIndex = lastClickIndex.value +1;}else{
minIndex = lastClickIndex.value;
maxIndex = rowIndex +1;}
props.data
.slice(minIndex, maxIndex).forEach((item)=> tableRef.value.toggleRowSelection(item,true));
lastSelectStatus =3;}
lastClickIndex.value = rowIndex;};// 处理表格复选框改变事件consthandleSelectionChange=(val)=>{emits("update:multipleSelection", val);};// 当前行变化触发(单选)consthandleCurrentChange=(val)=>{emits("current-change", val);};// 默认勾选watch(()=> props.selected,async(selectedRow)=>{if(selectedRow.length >0){awaitnextTick();
tableRef.value.clearSelection();
selectedRow.forEach((row)=>{// 注意:这里的row的引用必须和表格行的引用相同才能生效// 否则无法实现选中效果// 也就是说这里初始选择行的数据必须从渲染表格的数据那里取
tableRef.value.toggleRowSelection(row,undefined);});}else{
tableRef.value.clearSelection();}});// 表格出现时清空选择watch(()=> props.show,async(show)=>{if(show){awaitnextTick();
tableRef.value.clearSelection();}});</script><style scoped lang="scss">.ycd-table {
user-select: none;// 去除表格边框:deep(.el-table th.el-table__cell.is-leaf),:deep(.el-table td.el-table__cell){border:0;}// :deep(.el-table .el-table__row:not(:last-of-type) td.el-table__cell),:deep(.el-table .el-table__row td.el-table__cell),:deep(.el-table .el-table__header th.el-table__cell){
border-bottom: 1px solid #ebeef5;}:deep(.el-table__border-left-patch){width:0;
background-color: transparent;}:deep(.el-table--border::after),:deep(.el-table--border::before),:deep(.el-table--border .el-table__inner-wrapper::after),:deep(.el-table__inner-wrapper::before){width:0;
background-color: transparent;}// 选中行的颜色:deep(.el-table).table-selected-row {--el-table-tr-bg-color:var(--el-color-primary-light-9);}}</style>
使用时如下
multipleSelection为多选选择的数据
<ycd-table
:data="tableDataPage"
v-model:multipleSelection="multipleSelection"
v-loading="loading":type="1":show="tableShow">// el-table-column列配置</ycd-table>
本文转载自: https://blog.csdn.net/weixin_47365243/article/details/135967370
版权归原作者 void0086 所有, 如有侵权,请联系我们删除。
版权归原作者 void0086 所有, 如有侵权,请联系我们删除。