实现:
- 表格可编辑
- 可通过上下左右的键盘实现跳转,就是动态聚焦
- 表格只能输入数字
大家可能会想,只能输入数字我用el-input-number不就行了,但是我还需要实现上下左右的像excel一样,可用上下左右键跳转,方便我输入,el-input-number有自带的自增自减事件,你可以说那加一个el.preventDefault()不就好了,好不了一点,没有用,没有阻止就算了,按上箭头自增和跳转同时发生,我直接给自己气笑了!!!
<el-table :data="tableData" :span-method="arraySpanMethod" :cell-class-name="tableRowClassName" border :show-header="false">
<el-table-column type="index" label="序号" />
<el-table-column :prop="'amount'+index" v-for="(item,index) in activeNum" :key="index" >
<template #default="scope">
<div v-if="scope.row.isInput&&postData[index]&&postData[index].header">
<el-input v-numberOnly :controls="false" ref="autoFocus"
v-model="postData[index].enTraffic" placeholder="请输入"
@keyup="nextFocu($event,index, scope.row.index,1)"
@input="bindChangeForm($event,index,'enTraffic',1)"
class="inputDeep" />
</div>
</template>
</el-table-column>
</el-table>
@keyup事件放下面了,也有人会说拿ref做啊,直接就可以拿到上一个或者下一个,对不起,我做的表格并不规整,是两个table表格看似合并在一起的,上面可能有5个,下面有3个,并不是对齐的,并且都是动态生成表格,也就是说,id为‘el-id-2940-49’输入框的左边,可能是‘el-id-2940-149’,且整个页面有很多不规则表格,所以只能拿到他页面上的祖父元素们来做。
const nextFocu = (el, index, row, type) => {
let td = document.getElementById(el.srcElement.id).parentElement.parentElement.parentElement.parentElement.parentElement
if (el.keyCode == 39) {
if (td && td.nextElementSibling) {
let nextDom = td.nextElementSibling.querySelectorAll('input')[0]
nextDom ? nextDom.focus() : '';
}
} else if (el.keyCode == 37) {
if (td && td.previousElementSibling) {
let lastDom = td.previousElementSibling.querySelectorAll('input')[0];
lastDom ? lastDom.focus() : '';
}
} else if (el.keyCode == 38) {
let upDom = '';
let lastChilderDom = ''
if (type == 1 && row == 1) {
upDom = getParentElement(td, 'el-table__row').previousElementSibling;
upDom.childNodes[index + 2].querySelectorAll('input')[0].focus();
} else if (type == 2) {
upDom = getParentElement(td, 'el-table__inner-wrapper').parentElement.previousElementSibling;
lastChilderDom = upDom.querySelectorAll('.el-table__row')[upDom.querySelectorAll('.el-table__row').length - 1]
lastChilderDom.querySelectorAll('input')[index].focus();
} else if (type == 3) {
upDom = getParentElement(td, 'el-table__row').previousElementSibling;
if (upDom && upDom.querySelectorAll('.el-table__cell')) {
lastChilderDom = upDom.querySelectorAll('.el-table__cell')[index + 1];
lastChilderDom.querySelectorAll('input')[0].focus();
}
}
} else if (el.keyCode == 40) {
let downDom = ""
let lastChilderDom2 = ''
if (type == 1 && row == 0) {
downDom = getParentElement(td, 'el-table__row').nextElementSibling;
downDom.childNodes[index + 2].querySelectorAll('input')[0].focus();
} else if (type == 1 && row == 1) {
downDom = getParentElement(td, 'el-table__inner-wrapper').parentElement.nextElementSibling;
lastChilderDom2 = downDom.querySelectorAll('.el-table__row')[downDom.querySelectorAll('.el-table__row').length - 1];
let getDom = lastChilderDom2.querySelectorAll('input')[index];
getDom ? getDom.focus() : "";
} else if (type == 3) {
downDom = getParentElement(td, 'el-table__row').nextElementSibling;
if (downDom && downDom.querySelectorAll('.el-table__cell')) {
lastChilderDom2 = downDom.querySelectorAll('.el-table__cell')[index + 1];
lastChilderDom2.querySelectorAll('input')[0].focus();
}
}
}
}
至于只能输入数字,我做了一个自定义指令v-numberOnly,代码也贴下边。
export default {
beforeMount(el, binding) {
el.clickOutsideEvent = (event) => {
// 判断点击是否发生在el之外
if (!(el === event.target || el.contains(event.target))) {
// 如果是,执行绑定的方法
el.handler = function (event) {
let input = event.target;
input.value = input.value
.replace(/[^-|0-9.]/g, "")
.replace(/(\..*)\./g, "$1");
};
el.addEventListener("input", el.handler);
}
};
// 添加事件监听
document.addEventListener("click", el.clickOutsideEvent);
},
unmounted(el) {
// 移除事件监听
document.removeEventListener("click", el.clickOutsideEvent);
},
};
最后,可输入表格的css我也贴下边,请夸我贴心!
.el-collapse {
border-top: none;
border-bottom: none;
}
.el-collapse-item {
border-top: 1px solid #f5f5f5;
border-left: 1px solid #f5f5f5;
border-right: 1px solid #f5f5f5;
margin-bottom: 12px;
}
/deep/ .el-collapse-item__wrap {
background: #fafafa !important;
border-radius: 0px 0px 0px 0px;
border: 1px solid #e4e4e4;
padding: 17px;
box-sizing: border-box;
}
/deep/ .el-table .warning-row {
background: #e0eafb !important;
text-align: center;
}
/deep/ .el-table .success-row {
background: #ffeed9 !important;
text-align: center;
}
/deep/ .el-table .info-row {
background: #eaeaea !important;
text-align: center;
}
/deep/ .el-table--default .el-table__cell {
padding: 0;
}
/deep/ .el-table--default .cell {
height: 50px;
line-height: 50px;
padding: 0;
}
/deep/ .el-collapse-item__content {
padding-bottom: 0;
}
.inputDeep >>> .el-input.is-disabled .el-input__wrapper {
background: #fff;
}
.inputDeep {
width: 100%;
}
.inputDeep >>> .el-input__inner {
-webkit-appearance: none;
background-color: #fff;
background-image: none;
border-radius: 4px;
border: none !important;
width: 100%;
box-shadow: none !important;
}
.inputDeep >>> .el-input__inner:focus {
outline: none;
}
.inputDeep >>> .el-input__wrapper {
height: 50px;
line-height: 50px;
box-shadow: none !important;
}
.inputDeep >>> .el-input__wrapper:hover {
box-shadow: none !important;
}
.inputDeep >>> .el-textarea__inner {
height: 80px !important;
line-height: 40px !important;
min-height: 50px !important;
box-shadow: none !important;
border: none;
}
.inputDeep >>> .el-descriptions__table.is-bordered .el-descriptions__cell {
width: 100px;
text-align: center;
}