vue element-ui表格怎样自定义表头,动态添加表头,新增行、新增列、删除行、删除列
需求描述
根据项目需求,需要用户填写几行几列,表头自定义动态添加,用户可以手动新增行、新增列、删除行、删除列,怎么实现一起来看看吧~
1.自定义表头,表头里插入输入框
<el-form ref="historyForm" :model="historyForm" size="small">
<div class="table-box" @contextmenu.prevent.capture>
<el-table
:data="historyForm.tableData"
:loading="loading"
style="width: 100%"
class="list-table default-scrollbar"
size="mini"
@header-contextmenu="rightClickColShowFun"
@row-contextmenu="rightClickRowShowFun"
:cell-class-name="tableClassName"
border>
<el-table-column label="序号" align="center" width="50">
<template slot-scope="scope">
{{scope.$index+1}}
</template>
</el-table-column>
<el-table-column label="等位基因" align="center" prop="name" class-name="cellDefault">
<template slot-scope="scope">
<el-input v-model="scope.row.name" class="name-input"></el-input>
</template>
</el-table-column>
<el-table-column :label="'ABO-'+`${colList.length}`+'位点'" class-name="specital-title">
<el-table-column align="center" class-name="cellDefault" v-for="(item,index) in colList" :key="index" min-width="40">
<template #header>
<el-input v-model="colList[index]" size="mini" @change="setColName(index,colList[index])"/>
</template>
<template slot-scope="scope">
<el-input type="number" v-model.number="scope.row[item].value" @input="setInputVal" :class="scope.row[item].checked ? 'red' : ''"></el-input>
</template>
</el-table-column>
</el-table-column>
</el-table>
<div class="add-column" @click="addColSetting">+</div>
</div>
<div class="add-line" @click="addParamsSetting">+</div>
</el-form>
data() {
return {
// 遮罩层
loading: true,
// 表单参数-表格内容数据
historyForm: {
tableData: []
},
// 表头列表数组
colList: [],
isAddCol: true,
colNum: 0,
rowNum: 0,
currentId: null,
mouldName: "A101templete",
dialogRowVisible: false,// 新增行
dialogColVisible: false,// 新增列
currentClickRow: null,
currentClickCol: null,
resultList: [],
};
},
特别注意:
添加 #header 才能自定义插入表头,否则会出现input框不能进行输入的Bug。
2.默认初始化几行几列占位
例如当前为3行4列占位,效果如下图展示。
methods: {
// 根据默认几行几列初始化表格
init() {
for (let i = 0; i < this.colNum; i++) {
this.colList.push("");
}
for (let j = 0; j < this.rowNum; j++) {
if (j === 0) {
this.historyForm.tableData.push({
name: this.mouldName,
"": {
value: null,
checked: 0
}
});
}else {
this.historyForm.tableData.push({
name: null,
"": {
value: null,
checked: 0
}
});
}
}
},
}
3.新增行
// 新增行
methods: {
// 在数组最后添加一行
addParamsSetting () {
this.addList()
},
addList () {
let item = {
name: null,
};
for (let i in this.colList) {
item[this.colList[i]] = {
value: null,
checked: 0
}
}
this.historyForm.tableData.push(item);
},
}
4.新增列
methods: {
// 在数据最后新增一列
addColSetting() {
for (let i in this.colList) {
if (this.colList[i] === "") {
this.isAddCol = false;
}else {
this.isAddCol = true;
}
}
if (this.isAddCol) {
this.addColList();
}else {
this.$message.success("还有未填写的列");
}
},
// 新增列
addColList() {
let list = this.historyForm.tableData;
for (let i = 0; i < list.length; i++) {
list[i][""] = {
value: null,
checked: 0
};
}
this.colList.push("");
},
}
注意事项:
因为表头是自定义输入框动态添加的,所以需要限制用户先把表头填写完成,再进行填写单元格的内容,新添加列也同理,否则会出现数据重复的Bug。
5.右键点击行,进行删除行
想要删除行,首先要拿到rowIndex,我们可以利用:cell-class-name=“tableClassName”,拿到rowIndex,赋值给row,@row-contextmenu=“rightClickRowShowFun”,即可拿到行的索引,进行删除行操作。
methods: {
// 给数据的row、column赋index,便于进行删除行、删除列
tableClassName({row, column, rowIndex, columnIndex}) {
row.index = rowIndex;
column.index = columnIndex - 2;
if(rowIndex === 0){
return 'blue'
}
},
// 右键单击选中行-确认是否删除行
rightClickRowShowFun(row) {
this.currentClickRow = row.index;
this.dialogRowVisible = true;
},
// 确认删除行
submitFunRow() {
this.dialogRowVisible = false;
this.deleteRow(this.currentClickRow);
},
// 删除当前行
deleteRow (index) {
this.historyForm.tableData.splice(index, 1)
},
}
6.右键点击表头,进行删除列
想要删除列,首先要拿到columnIndex,我们可以利用:cell-class-name=“tableClassName”,拿到columnIndex,赋值给column,@header-contextmenu=“rightClickColShowFun”,即可拿到列的索引,进行删除列操作。
methods: {
// 给数据的row、column赋index,便于进行删除行、删除列
tableClassName({row, column, rowIndex, columnIndex}) {
row.index = rowIndex;
column.index = columnIndex - 2;
if(rowIndex === 0){
return 'blue'
}
},
// 右键单击选中行-确认是否删除列
rightClickColShowFun(column, event) {
this.currentClickCol = column.index;
this.dialogColVisible = true;
},
// 确认删除列
submitFunCol() {
this.dialogColVisible = false;
this.deleteCol(this.currentClickCol);
},
// 删除当前列
deleteCol (index) {
this.colList.splice(index, 1)
},
}
7.效果展示
单元格和表头内都插入的是输入框,写css样式可以进行修改输入框样式,我这里给单元格内的输入框限制了number类型(v-model.number),会出现上下增加数值的按钮,我给隐藏掉了,代码如下:
.cellDefault{
padding: 0!important;
.cell{
padding: 0!important;
input{
border: none;
border-radius: 0;
text-align: center;
background: #EEF8FF;
padding: 0;
}
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none !important;
margin: 0;
}
}
}
8.所有代码总结
<template>
<div class="app-container haplotype-detail default-scrollbar">
<div>
<el-form ref="historyForm" :model="historyForm" size="small">
<div class="table-box" @contextmenu.prevent.capture>
<el-table
:data="historyForm.tableData"
:loading="loading"
style="width: 100%"
class="list-table default-scrollbar"
size="mini"
@header-contextmenu="rightClickColShowFun"
@row-contextmenu="rightClickRowShowFun"
:cell-class-name="tableClassName"
border>
<el-table-column label="序号" align="center" width="50">
<template slot-scope="scope">
{{scope.$index+1}}
</template>
</el-table-column>
<el-table-column label="等位基因" align="center" prop="name" class-name="cellDefault">
<template slot-scope="scope">
<el-input v-model="scope.row.name" class="name-input"></el-input>
</template>
</el-table-column>
<el-table-column :label="'ABO-'+`${colList.length}`+'位点'" class-name="specital-title">
<el-table-column align="center" class-name="cellDefault" v-for="(item,index) in colList" :key="index" min-width="40">
<template #header>
<el-input v-model="colList[index]" size="mini" @change="setColName(index,colList[index])"/>
</template>
<template slot-scope="scope">
<el-input type="number" v-model.number="scope.row[item].value" @input="setInputVal" :class="scope.row[item].checked ? 'red' : ''"></el-input>
</template>
</el-table-column>
</el-table-column>
</el-table>
<div class="add-column" @click="addColSetting">+</div>
</div>
<div class="add-line" @click="addParamsSetting">+</div>
<div class="start-btn-box">
<el-button type="primary" @click="startComparisonFun" class="start-btn">开始对比</el-button>
</div>
</el-form>
</div>
<el-dialog
title="温馨提示"
:visible.sync="dialogRowVisible"
width="250px"
>
<span>确定删除此行数据嘛?</span>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogRowVisible = false">取 消</el-button>
<el-button type="primary" @click="submitFunRow">确 定</el-button>
</div>
</el-dialog>
<el-dialog
title="温馨提示"
:visible.sync="dialogColVisible"
width="250px"
>
<span>确定删除此列数据嘛?</span>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogColVisible = false">取 消</el-button>
<el-button type="primary" @click="submitFunCol">确 定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
name: "haplotypeDetail",
data() {
return {
// 遮罩层
loading: true,
// 表单参数-表格内容数据
historyForm: {
tableData: []
},
// 表头列表数组
colList: [],
isAddCol: true,
colNum: 0,
rowNum: 0,
currentId: null,
mouldName: "A101templete",
dialogRowVisible: false,// 新增行
dialogColVisible: false,// 新增列
currentClickRow: null,
currentClickCol: null,
resultList: [],
};
},
methods: {
// 根据默认几行几列初始化表格
init() {
for (let i = 0; i < this.colNum; i++) {
this.colList.push("");
}
for (let j = 0; j < this.rowNum; j++) {
if (j === 0) {
this.historyForm.tableData.push({
name: this.mouldName,
"": {
value: null,
checked: 0
}
});
}else {
this.historyForm.tableData.push({
name: null,
"": {
value: null,
checked: 0
}
});
}
}
},
// 在数组最后添加一行
addParamsSetting () {
this.addList()
},
// 新增行
addList () {
let item = {
name: null,
};
for (let i in this.colList) {
item[this.colList[i]] = {
value: null,
checked: 0
}
}
this.historyForm.tableData.push(item);
},
// 删除当前行
deleteRow (index) {
this.historyForm.tableData.splice(index, 1)
},
// 在数据最后新增一列
addColSetting() {
for (let i in this.colList) {
if (this.colList[i] === "") {
this.isAddCol = false;
}else {
this.isAddCol = true;
}
}
if (this.isAddCol) {
this.addColList();
}else {
this.$message.success("还有未填写的列");
}
},
// 新增列
addColList() {
let list = this.historyForm.tableData;
for (let i = 0; i < list.length; i++) {
list[i][""] = {
value: null,
checked: 0
};
}
this.colList.push("");
},
// 修改表头名fun
setColName(index, val) {
let list = this.historyForm.tableData;
for (let i = 0; i < list.length; i++) {
this.$set(list[i],val,{
value: null,
checked: 0
})
}
this.$forceUpdate();
},
// 输入内容数据的fun
setInputVal() {
for (let i in this.colList) {
if (this.colList[i] === "") {
this.isAddCol = false;
}else {
this.isAddCol = true;
}
}
if (!this.isAddCol) {
this.$message.success("请先填写完成所有表头内容,且确保无误!");
let list = this.historyForm.tableData;
for (let j = 0; j < list.length; j++) {
if (list[j][""]) {
list[j][""] = {
value: null,
checked: 0
};
}
}
}
},
// 右键单击选中行-确认是否删除行
rightClickRowShowFun(row, column, event) {
this.currentClickRow = row.index;
this.dialogRowVisible = true;
},
// 右键单击选中行-确认是否删除列
rightClickColShowFun(column, event) {
this.currentClickCol = column.index;
this.dialogColVisible = true;
},
// 确认删除行
submitFunRow() {
this.dialogRowVisible = false;
this.deleteRow(this.currentClickRow);
},
// 给数据的row、column赋index,便于进行删除行、删除列
tableClassName({row, column, rowIndex, columnIndex}) {
row.index = rowIndex;
column.index = columnIndex - 2;
if(rowIndex === 0){
return 'blue'
}
},
// 确认删除列
submitFunCol() {
this.dialogColVisible = false;
this.deleteCol(this.currentClickCol);
},
// 删除当前列
deleteCol (index) {
this.colList.splice(index, 1)
},
},
}
</script>
<style lang="scss">
.haplotype-detail{
.list-table{
background: #EEF8FF;
&.el-table thead.is-group th.el-table__cell{
background: #EEF8FF;
}
&.el-table td.el-table__cell{
background: #EEF8FF;
color: #0083D7;
}
.name-input{
input{
color: #0083D7;
}
}
.specital-title{
color: #0083D7;
font-size: 16px;
font-family: Source Han Sans CN;
font-weight: bold;
}
}
.el-table--enable-row-hover .el-table__body tr:hover > td.el-table__cell{
background: #A0D8FF;
.cell input{
background: #A0D8FF;
}
}
.cellDefault{
padding: 0!important;
.cell{
padding: 0!important;
input{
border: none;
border-radius: 0;
text-align: center;
background: #EEF8FF;
padding: 0;
}
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none !important;
margin: 0;
}
}
}
th.cellDefault{
input{
background: #F5F7FA;
}
}
.red{
background: #E8CCCB;
input{
background: #E8CCCB!important;
color: #DD262F;
}
}
.blue{
background: #A0D8FF!important;
input{
background: #A0D8FF!important;
}
}
}
版权声明:本文为ALSO666原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。