备注的输入框按回车可以直接插入一行
直接上垃圾代码需要的自己改去吧
html部分
<template>
<div class="right">
<div style="width: 100%;margin: 0 auto;text-align: center; margin-bottom: 50px;">
<div style=" margin-top: 30px; text-align: left;padding: 20px;min-height: 600px;">
<div style="display: flex;display: flex;">
<div class="topinfo setBackgroundBlue" style="width: 150px;"> 序号</div>
<div class="topinfo setBackgroundBlue" style="width: 280px;">名称</div>
<div class="topinfo setBackgroundBlue" style="width: 200px;">
<div style="height: 25px;line-height: 25px;">
时间
</div>
<div style="display: flex;">
<div class="topinfo" style="height: 25px;line-height: 25px;flex: 1.5;">
年
</div>
<div class="topinfo" style="height: 25px;line-height: 25px;flex: 1;">
月
</div>
<div class="topinfo" style="height: 25px;line-height: 25px;flex: 1;">
日
</div>
</div>
</div>
<div class="topinfo setBackgroundBlue" style="width: 70px;"> 页数</div>
<!-- <div class="topinfo" style="width: 70px;"> 份数</div> -->
<div class="topinfo setBackgroundBlue" style="flex: auto;;">备注</div>
</div>
<div style="margin-bottom: 100px;" @keydown="handleKeydown" tabindex="0">
<el-table :data="treeData1" style="width: 100%;margin-bottom: 20px;" row-key="nodeId" border
:cell-class-name="setBackgroundBlue" class="exporttable" :show-header="false"
default-expand-all :tree-props="{ children: 'children' }"
:cell-style="{ borderColor: 'black' }" :header-cell-style="{ borderColor: 'black' }">
<el-table-column prop="nodeIndex" label="序号" width="150">
<template slot-scope="scope">
<div v-if="!scope.row.children || scope.row.children.length == 0">
{{ getindex(scope.row) }}
<!-- <el-input v-model="scope.row.nodeIndex" placeholder="请输入"></el-input> -->
</div>
<div v-else>
{{ scope.row.nodeIndex }}
</div>
</template>
</el-table-column>
<el-table-column prop="nodeName" label="履历材料" width="280">
<template slot-scope="scope">
<div :style="{ width: '100%' }"
v-if="!scope.row.children || scope.row.children.length == 0">
<el-input v-model="scope.row.nodeName" placeholder="名称"
@focus="handleFocus"></el-input>
</div>
<div v-else>
{{ scope.row.nodeName }}
</div>
</template>
</el-table-column>
<el-table-column prop="nodeDate" label="时间" width="200">
<template slot-scope="scope">
<div v-if="!scope.row.children || scope.row.children.length == 0"
style="display: flex;">
<!-- <el-date-picker type="date" v-model="scope.row.nodeDate" format="yyyy-MM-dd"
value-format="yyyy-MM-dd" :style="{ width: '100%' }" placeholder="请选择"
clearable></el-date-picker> -->
<el-input v-model="scope.row.year" placeholder="年" style="flex: 1.5;"
@focus="handleFocus"></el-input>
<el-input v-model="scope.row.month" placeholder="月" style="flex: 1;"
@focus="handleFocus"></el-input>
<el-input v-model="scope.row.day" placeholder="日" style="flex: 1;"
@focus="handleFocus"></el-input>
</div>
</template>
</el-table-column>
<el-table-column prop="nodePages" label="页数" width="70">
<template slot-scope="scope">
<div v-if="!scope.row.children || scope.row.children.length == 0">
<el-input v-model="scope.row.nodePages" placeholder="0"
@focus="handleFocus"></el-input>
</div>
<div v-else>
{{ scope.row.nodePages }}
</div>
</template>
</el-table-column>
<!-- <el-table-column prop="nodeCopies" label="份数" width="70">
<template slot-scope="scope">
<div v-if="!scope.row.children || scope.row.children.length == 0">
<el-input v-model="scope.row.nodeCopies" placeholder="0"></el-input>
</div>
<div v-else>
{{ scope.row.nodeCopies }}
</div>
</template>
</el-table-column> -->
<el-table-column prop="nodeNotes" label="备注" min-width="120">
<template slot-scope="scope">
<div v-if="!scope.row.children || scope.row.children.length == 0"
:style="{ width: '100%' }"
@keydown.enter="handleClickRow(scope.row, 'hang')">
<el-input v-model="scope.row.nodeNotes" placeholder="备注"
@focus="handleFocus"></el-input>
</div>
<div v-else>
{{ scope.row.nodeNotes }}
</div>
</template>
</el-table-column>
<el-table-column label="操作" width="aotu" :align="'center'">
<template slot-scope="scope">
<div>
<el-button @click="handleClickRow(scope.row, 'jiedian')" type="text"
v-if="findNodeLevelAndPosition(treeData1, scope.row).length <= 1"
size="small">+节点</el-button>
<el-button @click="handleClickRow(scope.row, 'zjd')" type="text"
v-if="!scope.row.nodeDate && findNodeLevelAndPosition(treeData1, scope.row).length < 2"
size="small">+子节点</el-button>
<el-button @click="handleClickRow(scope.row, 'zx')" type="text"
v-if="scope.row.children && findNodeLevelAndPosition(treeData1, scope.row).length < 3"
size="small">+子项</el-button>
<el-button @click="handleClickRow(scope.row, 'del')" type="text"
size="small">删除</el-button>
</div>
</template>
</el-table-column>
</el-table>
</div>
</div>
</template>
js部分
<script>
import { customAlphabet } from 'nanoid'//生成id用的
export default {
data() {
return {
treeData1: [],
selectedKey: '',
defaultProps: {
children: 'children',
label: 'label'
},
currentRow: 0,//现在是第几列
currentColumn: 0,//现在是第几行
columns: 6,//每行有多少个输入框
}
},
created() {
},
computed: {
numberOfColumns() {
return this.currentColumn * this.columns
},
numberOfRows() {
return document.querySelectorAll('.exporttable input').length - 1
}
},
mounted() {
//第一个输入框自动获焦 使键盘可控制焦点
setTimeout(() => {
let inputs = document.querySelectorAll('.exporttable input');
inputs[0].focus();
}, 500);
},
methods: {
//鼠标点击输入框后修正焦点位置
handleFocus(event) {
let selected = event.target
let inputs = document.querySelectorAll('.exporttable input')
let index = Array.from(inputs).indexOf(selected);
this.currentRow = index % this.columns
this.currentColumn = Math.floor(index / this.columns)
},
//键盘上下左右移动input获焦
handleKeydown(event) {
switch (event.keyCode) {
case 38: // 上
if (this.currentColumn > 0) {
console.log("上");
this.currentColumn--;
console.log("现在是第几行", this.currentColumn);
}
break;
case 40: //下
if (this.currentColumn < this.numberOfRows / 6 - 1) {
console.log("下");
this.currentColumn++;
console.log("现在是第几行", this.currentColumn);
}
break;
case 37: // 左
if (this.currentRow > 0) {
console.log("左");
this.currentRow--;
console.log("现在是第几列", this.currentRow);
}
break;
case 39: // 右
if (this.currentRow < this.columns - 1) {
console.log("右");
this.currentRow++;
console.log("现在是第几列", this.currentRow);
}
break;
}
const inputs = document.querySelectorAll('.exporttable input');
const index = this.numberOfColumns + this.currentRow; // Calculate input index based on row and column
if (inputs.length > index) {
inputs[index].focus();
}
},
//计算序号
getindex(clickedRow) {
const positionInTree = this.findNodeLevelAndPosition(this.treeData1, clickedRow);
if (positionInTree.length == 1) {
return this.treeData1.indexOf(clickedRow) + 1;
}
if (positionInTree.length == 2) {
return this.treeData1[positionInTree[0]].children.indexOf(clickedRow) + 1;
}
if (positionInTree.length == 3) {
return this.treeData1[positionInTree[0]].children[positionInTree[1]].children.indexOf(clickedRow) + 1;
}
},
setBackgroundBlue({ row }) {
if (!row.children || row.children.length == 0) {
} else {
return 'setBackgroundBlue'
}
},
//还原在tree中的路径
findNodeLevelAndPosition(data, clickedRow) {
const path = [];
const findPath = (node, targetId) => {
for (let j = 0; j < node.length; j++) {
if (node[j].nodeId === targetId) {
path.push(j);
return true;
}
if (node[j].children) {
for (let i = 0; i < node[j].children.length; i++) {
const childs = node[j].children[i];
if (childs.nodeId == targetId) {
path.push(j);
path.push(i);
return true;
}
if (node[j].children[i].children) {
for (let k = 0; k < node[j].children[i].children.length; k++) {
const child = node[j].children[i].children[k];
if (child.nodeId == targetId) {
path.push(j);
path.push(i);
path.push(k);
return true;
}
}
}
}
}
}
};
findPath(data, clickedRow.nodeId);
return path;
},
handleClickRow(clickedRow, type) {
const positionInTree = this.findNodeLevelAndPosition(this.treeData1, clickedRow);
console.log("此行在数据中的位置路径:", positionInTree);
let nanoid = customAlphabet('1234567890', 4)
// let id = nanoid()
console.log("id:", positionInTree.length);
if (type == 'del') {
if (positionInTree.length == 1) {
this.treeData1.splice(positionInTree[0], 1,)
}
if (positionInTree.length == 2) {
this.treeData1[positionInTree[0]].children.splice(positionInTree[1], 1,)
}
if (positionInTree.length == 3) {
this.treeData1[positionInTree[0]].children[positionInTree[1]].children.splice(positionInTree[2], 1,)
}
}
if (type == 'jiedian') {
let data = {
nodeId: nanoid(),
nodeIndex: "",
nodeName: '',
nodeNotes: "",
children: []
}
if (positionInTree.length == 1) {
this.treeData1.splice(positionInTree[0] + 1, 0, data)
}
if (positionInTree.length == 2) {
this.treeData1[positionInTree[0]].children.splice(positionInTree[1] + 1, 0, data)
}
}
if (type == 'zjd') {
if (positionInTree.length == 1) {
this.treeData1[positionInTree[0]].children.push({
nodeId: nanoid(),
nodeIndex: "",
nodeName: '',
nodeNotes: "",
children: []
})
}
if (positionInTree.length == 2) {
}
}
if (type == 'zx') {
if (positionInTree.length == 1) {
this.treeData1[positionInTree[0]].children.push({
nodeId: nanoid(),
nodeIndex: "",
nodeName: '',
nodeDate: '',
nodePages: null,
nodeNotes: "",
nodeCopies: "",
children: [],
})
}
if (positionInTree.length == 2) {
this.treeData1[positionInTree[0]].children[positionInTree[1]].children.push({
nodeId: nanoid(),
nodeIndex: "",
nodeName: '',
nodeDate: '',
nodePages: null,
nodeNotes: "",
nodeCopies: "",
})
}
}
if (type == 'hang') {
if (positionInTree.length == 2) {
this.treeData1[positionInTree[0]].children.push({
nodeId: nanoid(),
nodeIndex: "",
nodeName: '',
nodeDate: '',
nodePages: null,
nodeNotes: "",
nodeCopies: "",
children: [],
})
}
if (positionInTree.length == 3) {
this.treeData1[positionInTree[0]].children[positionInTree[1]].children.push({
nodeId: nanoid(),
nodeIndex: "",
nodeName: '',
nodeDate: '',
nodePages: null,
nodeNotes: "",
nodeCopies: "",
})
}
}
}
}
}
</script>
样式
<style lang="scss" scoped>
.topinfo {
height: 50px;
line-height: 50px;
text-align: center;
border: 1px solid black;
}
.exporttable {
border: solid 1px black;
}
::v-deep .cell {
display: flex;
align-items: center;
}
::v-deep .setBackgroundBlue {
background-color: #DAE5F6;
}
</style>