Element中Tree树结构组件中实现Ctrl和Shift多选

直接上图

<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 = [];
};

参考:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天弈初心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值