一、描述
Table内使用键盘方向键操作单元格内input元素
二、基础
@keyup.ctrl.37 ctrl + ←
@keyup.ctrl.38 ctrl + ↑
@keyup.ctrl.39 ctrl + →
@keyup.ctrl.40 ctrl + ↓
三、实现
<template> <div class="sp-container"> <table class="sp-table" @keyup.ctrl.37='LeftMoving' @keyup.ctrl.38='TopMoving' @keyup.ctrl.39='RightMoving' @keyup.ctrl.40='BottomMoving' > <tr v-for="rows of tableData" :key="rows.key"> <td class="sp-cell" v-for="cell of rows.row" :key="cell.index"> <input type="text" class="sp-cell-input" :ref="cell.rf" /> </td> </tr> </table> </div> </template> <script> export default { name: "sp-table", data() { return { top: 1, //单元格最小索引 bottom: 15, //单元格最大索引 step: 5, //上下移动的步长 focusIndex: 1, //当前焦点所在的索引 tableData: [ //数据源 (文章下方有单独的数据源代码块,数据源结构大致如此) { row: [ { rf: "InnerInput1", index: 1 }, { rf: "InnerInput2", index: 2 }, { rf: "InnerInput3", index: 3 }, { rf: "InnerInput4", index: 4 }, { rf: "InnerInput5", index: 5 } ], key: 1 } ] }; }, mounted() { //焦点默认在第一个 this.$refs["InnerInput1"][0].focus(); }, methods: { LeftMoving() { //向左移动 //如果向左移动到首个单元格,阻止操作 if (this.focusIndex == 1) { return false; } //向左移动,当前焦点索引 - 1 this.focusIndex--; //拼接 ref 名称 let rf = "InnerInput" + this.focusIndex; //设置目标的焦点 this.$refs[rf][0].focus(); }, TopMoving() { //向上移动 //如果移动到首行,阻止操作 if (this.focusIndex - this.step < this.top) { return false; } //向上移动,当前焦点索引 - 步长 this.focusIndex -= this.step; //拼接 ref 名称 let rf = "InnerInput" + this.focusIndex; //设置目标焦点 this.$refs[rf][0].focus(); }, RightMoving() { //向右移动 //如果移动到最后一个单元格,阻止操作 if (this.focusIndex == this.bottom) { return false; } //向右移动,当前焦点索引 + 1 this.focusIndex++; //拼接 ref 名称 let rf = "InnerInput" + this.focusIndex; //设置目标焦点 this.$refs[rf][0].focus(); }, BottomMoving() { //向下移动 //如果移动到最后一行,阻止操作 if (this.focusIndex + this.step > this.bottom) { return false; } //向下移动,当前焦点索引 + 步长 this.focusIndex += this.step; //拼接 ref 名称 let rf = "InnerInput" + this.focusIndex; console.log(this.$refs[rf]) //设置目标焦点 this.$refs[rf][0].focus(); } } }; </script>

tableData: [ //数据源 { row: [ { rf: "InnerInput1", index: 1 }, { rf: "InnerInput2", index: 2 }, { rf: "InnerInput3", index: 3 }, { rf: "InnerInput4", index: 4 }, { rf: "InnerInput5", index: 5 } ], key: 1 }, { row: [ { rf: "InnerInput6", index: 6 }, { rf: "InnerInput7", index: 7 }, { rf: "InnerInput8", index: 8 }, { rf: "InnerInput9", index: 9 }, { rf: "InnerInput10", index: 10 } ], key: 2 }, { row: [ { rf: "InnerInput11", index: 11 }, { rf: "InnerInput12", index: 12 }, { rf: "InnerInput13", index: 13 }, { rf: "InnerInput14", index: 14 }, { rf: "InnerInput15", index: 15 } ], key: 3 } ]

<style scoped> .sp-container { width: 100%; height: 100%; margin-top: 120px; } .sp-table { width: 606px; height: 86px; margin: 0 auto; border-left: 2px solid #000; border-top: 2px solid #000; } .sp-cell { width: 120px; height: 40px; border-right: 2px solid #000; border-bottom: 2px solid #000; padding: 2px; box-sizing: border-box; } .sp-cell-input { width: 95%; height: 100%; font-size: 16px; } </style>
四、效果
五、注意事项
- 在使用 this.$refs[rf] 时,后面必须加 [0],因为此时 this.$refs[rf] 不是一个DOM元素,而是一个数组
谦良恭卑,信诚实至;
生活不易,共勉同求。