直接上图
<el-tree
:data="treeData"
@node-click="handleNodeClick"
:default-expand-all="true"
:highlight-current="true"
node-key="id"
:expand-on-click-node="true"
ref="treeRef"
></el-tree>
// node点击事件
const handleNodeClick = async (data, node) => {
let event_ = window.event || arguments.callee.caller.arguments[0];
let shiftKeyDowned = event_.shiftKey;
let ctrlKeyDowned = event_.ctrlKey;
if (ctrlKeyDowned == false && shiftKeyDowned == false) {
// 都没有点击
treeRef.value.setCheckedKeys([data.id]);
batchSelectTree.value = [data];
} else if (ctrlKeyDowned == true && shiftKeyDowned == false) {
//只点击ctrl
if (node.checked) {
treeRef.value.setChecked(data.id, false);
let index = batchSelectTree.value
.map((el) => el.id)
.indexOf(data.id);
batchSelectTree.value.splice(index, 1);
} else {
treeRef.value.setChecked(data.id, true);
batchSelectTree.value.push(data);
}
} else if (ctrlKeyDowned == false && shiftKeyDowned == true) {
//只点击shift
/**
* 思路:通过计算开始索引到结束索引的差值,计算这段区间里有多少个数据,
* 并且取数组第一个作为开始索引,往数组里push,每次shift,清空数据,因开始索引不会变化,只需要计算结束的索引即可。
* 1.需要先判断一开始有没有选中一个。(以下情况,都是选中了一个的情况)
* 2.往上选择,每次清空,从下往上把数据push到数组里,for --
* 3.往下选择,每次清空,从上往下把数据push到数组里,for ++
* 原始思路(但不完整实现):
* 也是通过计算开始索引到结束索引的差值,计算这段区间里有多少个数据,
* 但是是取数组最后一个作为开始索引,记录上次的开始索引和结束索引,插入到数组时是用unshift
* 与vscode 的shift多选的差异:
* 因每次shift都会清空上一次的选择,没有实现ctrl和shift交替使用,目前只支持同一文件夹里多选,且不支持多层级多选
* 欢迎补充完善
*/
// 需要判断一开始有没有空的
// 若是一开始选择数组里是空的,直接retrun,不让操作,(或是把当前激活的窗口选中,并放到数组中,暂不实现这种方式)
if (batchSelectTree.value.length == 0) return;
let showNodes = node.parent.childNodes;
let start = batchSelectTree.value[0]; //数值列里第一个
let startIndex = showNodes.map((el) => el.data.id).indexOf(start.id);
let endIndex = showNodes.map((el) => el.data.id).indexOf(data.id); //当前的node
// console.log(start, startIndex, endIndex, "开始索引");
if (startIndex > endIndex) {
// 往上选择
await cancelSelectTree();
for (let index = startIndex; index >= endIndex; index--) {
const el = showNodes[index];
treeRef.value.setChecked(el.data.id, true);
batchSelectTree.value.push(el.data);
}
} else {
// 往下选择
await cancelSelectTree();
for (let index = startIndex; index <= endIndex; index++) {
const el = showNodes[index];
treeRef.value.setChecked(el.data.id, true);
batchSelectTree.value.push(el.data);
}
}
} else {
// 都有点击,当做都没点击处理
treeRef.value.setCheckedKeys([data.id]);
batchSelectTree.value = [data];
}
};
// 取消原来的选中
const cancelSelectTree = () => {
batchSelectTree.value.forEach((el) => {
treeRef.value.setChecked(el.id, false);
});
batchSelectTree.value = [];
};
参考: