element Plus表单表格实现键盘上下键切换实现表格行的光标移动

277 阅读1分钟

Vue3+Ts+ElementPlus项目想要实现FromTable表单表格如同excel一样光标上下左右移动,需要通过以下两个步骤完成:

1、通过获取表格中每一行的每个输入框的dom并设置唯一的key存入对象

image.png

// 实现键盘上下键选中
const labelRefs = reactive<Record<string, HTMLElement>>({});

2、通过上下光标的keyCode值去获取焦点

image.png

const moveFocus = (event: any, index: number, key: string) => {
    const keyField = [
        "goodsName",
        "goodsMode",
        "proMode",
        "goodsNo",
        "curProvideQuantity",
        "categoryType",
        "proCode",
        "proDate",
        "invalidDate",
        "maintainCycle",
        "producer",
        "qualityStateId",
        "remark",
    ];
    if (event.keyCode === 13) {
        // 回车向右
        if (index === localData.handoverList.length - 1 && key === keyField[keyField.length - 1]) {
            return;
        }
        labelRefs[index + key].blur();
        if (key === keyField[keyField.length - 1]) {
            labelRefs[index + 1 + keyField[0]].focus();
        } else {
            const nextKeyIndex = keyField.findIndex((item) => item === key) + 1;
            nextTick(() => {
                labelRefs[index + keyField[nextKeyIndex]].focus();
            });
        }
    }
    // 向上 38
    if (event.keyCode === 38) {
        if (index === 0) {
            return; // 第一行无法向上
        }
        labelRefs[index + key].blur();
        nextTick(() => {
            labelRefs[index - 1 + key].focus();
        });
    }
    // 向下 40
    if (event.keyCode === 40) {
        if (index === localData.handoverList.length - 1) {
            return; // 最后一行无法向下
        }
        labelRefs[index + key].blur();
        nextTick(() => {
            labelRefs[index + 1 + key].focus();
        });
    }
    // 向左 37
    if (event.keyCode === 37) {
        if (index === 0 && key === keyField[0]) {
            return;
        }
        labelRefs[index + key].blur();
        // 当前行第一个,跳转上一行最后一个
        if (key === keyField[0]) {
            labelRefs[index - 1 + keyField[keyField.length - 1]].focus();
        } else {
            // 跳转上一个
            const preKeyIndex = keyField.findIndex((item) => item === key) - 1;
            nextTick(() => {
                labelRefs[index + keyField[preKeyIndex]].focus();
            });
        }
    }
    // // 向右 39
    if (event.keyCode === 39) {
        if (index === localData.handoverList.length - 1 && key === keyField[keyField.length - 1]) {
            return;
        }
        labelRefs[index + key].blur();
        // 最后一行最后一个,跳转下一行第一个
        if (key === keyField[keyField.length - 1]) {
            labelRefs[index + 1 + keyField[0]].focus();
        } else {
            // 跳转下一个
            const nextKeyIndex = keyField.findIndex((item) => item === key) + 1;
            nextTick(() => {
                labelRefs[index + keyField[nextKeyIndex]].focus();
            });
        }
    }
};