vue element-ui表格怎样自定义表头,动态添加表头,新增行、新增列、删除行、删除列
- 需求描述
- 1.自定义表头,表头里插入输入框
- 2.默认初始化几行几列占位
- 3.新增行
- 4.新增列
- 5.右键点击行,进行删除行
- 6.右键点击表头,进行删除列
- 7.效果展示
- 8.所有代码总结
需求描述
根据项目需求,需要用户填写几行几列,表头自定义动态添加,用户可以手动新增行、新增列、删除行、删除列,怎么实现一起来看看吧~
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-dialogtitle="温馨提示":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-dialogtitle="温馨提示":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("");},// 修改表头名funsetColName(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();},// 输入内容数据的funsetInputVal() {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;}}
}