elementUI表格动态添加删除__Vue.js
粉丝福利 : 关注VUE中文社区公众号,回复视频领取粉丝福利
前言:
我只简单的描述一下需求:基于elementUI的后台管理系统需要实现一个自定义表格,所有内容均可自定义输入,包括表头(指的是后台输入定义前台显示的的表头,而不是后台页面表头)。表格需要动态添加和删除行和列,以及表格自身也可动态添加或者删除。说实话,这个东西看着确实是没啥,结果做的时候真的把我恶心到了,可能实现的并不是很好,各位大佬请多担待。我写这篇博客的目的也只是为了记录一下这个问题而已。
具体实现:
安装elementUI
npm install babel-plugin-component -D'
完整引入
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
功能实现:
- html部分
<div id="app">
<el-form>
<div v-for="(item,index) in tab" :key="index">
<!-- 自定义表格的标题 -->
<el-input v-model="item.title"></el-input>
<el-table :data="item.data" size="small" empty-text="暂无数据" border :header-cell-style="{background:'#eef1f6',color:'#606266'}">
<el-table-column v-for="col in cols[index]" align="center">
<template slot-scope="scope">
<el-input v-model="scope.row[col.prop]" value-key="index" size="small"></el-input>
</template>
</el-table-column>
<el-table-column label="操作" align="center">
<template slot-scope="scope">
<el-button type="text" size="mini" @click="addLine(index,scope.$index)">添加行</el-button>
<el-button type="text" size="mini" @click="delLine(index,scope.$index)">删除行</el-button>
<el-button type="text" size="mini" @click="addCol(index)">添加列</el-button>
<el-button type="text" size="mini" @click="delCol(index)">删除列</el-button>
</template>
</el-table-column>
</el-table>
<el-button type="primary" @click="addTab">添加表格</el-button>
<el-button @click="delTab">删除表格</el-button>
</div>
</el-form>
</div>
- js部分:
import Vue from 'vue';
export default Vue.extend({
name: 'App',
data () {
return {
//默认表格为4*4的格式
tab: [{
title: '',
data: [
{
column1: '',
column2: '',
column3: '',
column4: ''
},
{
column1: '',
column2: '',
column3: '',
column4: ''
},
{
column1: '',
column2: '',
column3: '',
column4: ''
},
{
column1: '',
column2: '',
column3: '',
column4: ''
}
]
}],
cols: [
[
{prop:'column1'},
{prop:'column2'},
{prop:'column3'},
{prop:'column4'}
]
]
}
},
methods: {
//添加行
addLine (tabIdx,lineIdx) {
//当前数据格式:{column1: "1",column2: "2",column3: "3",column4: "4"}
//目标数据格式:{column1: "", column2: "", column3: "", column4: ""}
//处理完之后push到data数据列表
let line = {};
let tabKeys = Object.keys(this.tab[tabIdx].data[lineIdx]);
tabKeys.forEach(item=>{
line[item] = '';
})
this.tab[tabIdx].data.push(line);
},
//删除行
delLine (tabIdx,lineIdx) {
//截取当前行的数据,剩下的数据就是删除后的数据
this.tab[tabIdx].data.splice(lineIdx,1);
},
//添加列
addCol (tabIdx) {
let col = this.cols[tabIdx].length + 1;
let prop = "column" + col;
let title = {
prop
};
//在data每一个对象中插入一个新增列
let data = this.tab[tabIdx].data;
data.forEach(item=>{
//item[prop] = '';//此写法vue检测不到,必须使用vue.set方法
Vue.set(item,prop,'');
});
//数据添加后,必须添加表头的数据,否则就算数据变更了也渲染不出来
this.cols[tabIdx].push(title);
},
//删除列
delCol (tabIdx) {
let len = this.cols[tabIdx].length;
let data = this.tab[tabIdx].data;
let prop = "column" + len;
data.forEach(item=>{
//删除数组对象每一行中的该元素,就是删除整列
Vue.delete(item,prop);
});
this.cols[tabIdx].splice(len-1,1);
},
//增加表格
addTab () {
//该处不能写成let newTab = this.tab;this.tab是一个变量,而需要push进去的却是一个常量
const newTab = {
title: '',
data: [
{
column1: '',
column2: '',
column3: '',
column4: ''
},
{
column1: '',
column2: '',
column3: '',
column4: ''
},
{
column1: '',
column2: '',
column3: '',
column4: ''
},
{
column1: '',
column2: '',
column3: '',
column4: ''
}
]
};
this.tab.push(newTab);
const prop = [
{prop:'column1'},
{prop:'column2'},
{prop:'column3'},
{prop:'column4'}
];
this.cols.push(prop);
},
//删除表格
delTab () {
let len = this.tab.length - 1;
this.tab.splice(len,1);
}
}
});
注:样式请根据自己需要自定义
数据处理
- js部分
methods: {
subForm () {
//后端存储是以多维数组的格式进行存储的表单数据的,而前端是以数组对象的格式进行数据绑定的,提交表单时就需要做数据的格式转化
let tab = this.tab.map(item=>{//能对每一个表格的数据同时进行处理
let arrs = [];
item.data.forEach(item=>{
let arr = Object.values(item);//获取表格中每一行的数据,并将其转化为数组
arrs.push(arr);//将每一行的数据push到整个表格的数组中
});
return arrs;
});
let data = this.tab.map((item,index)=>{//将标题处理到每一个表格的数组中
return {
title: item.title,
table: tab[index]
}
});
console.log(data);
},
//数据回显
getData () {
//本来在工作中是请求的数据接口,既然没有,那我自己写一个后端的默认数据,进行转化后回显数据
const data = [{//实际上这就是我传入时转换出来的数据格式
title:'这是第一个表格',
table:[
["1", "2", "3", "4"],
["1", "2", "3", "4"],
["1", "2", "3", "4"],
["1", "2", "3", "4"]
]
}];
this.tab = data.map(item=>{
let data = item.table.map(item=>{
let obj = {};
item.forEach((item,index)=>{
obj[`column${index+1}`] = item;
});
return obj;
});
return {
title: item.title,
data: data
}
});
this.cols = this.tab.map(item=>{//必须还原表头,不然会出现bug
let prop = Object.keys(item.data[0]);
let arr = [];
prop.forEach(item=>{
let obj = {};
obj['prop'] = item;
arr.push(obj);
});
return arr;
});
}
}
created(){
this.getData();
}
参考文献:
后记:
此文仅为记录工作中遇到的问题,且纯原创,百度无任何参考,正因如此才写了此文。如果后续有小伙伴遇到类似的需求,可参考此文!
版权声明:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 作者: 前端菜鸡的全桟之路 原文链接:https://juejin.im/post/6869382712089247751