vue+elementui实现动态多级表头+合并单元格+⾃适应列宽1.动态多级表头的实现
因为项⽬需求是要根据不同查询条件,显⽰不同的表头,所以需要动态渲染表头
在表格渲染的时候,label和prop要对应起来,简单⼀点的办法就是让后端传过来,这是我给后端提供的格式
title:[
{label:'⼀级标题1',item:[//label为表头的内容,prop为对应的字段名(注意字段名要和后端传过来的数据列表的字段名⼀致){label:'⼆级标题1',item:[
{label:'三级标题1',prop:'value1'},
{label:'三级标题2',prop:'value2'},
{label:'三级标题3',prop:'value3'},
{label:'三级标题4',prop:'value4'},
{label:'三级标题5',prop:'value5'},
]},
{label:'⼆级标题1',prop:'value6'},
{label:'⼆级标题2',prop:'value7'},
{label:'⼆级标题3',prop:'value8'},
{label:'⼆级标题4',prop:'value9'},
{label:'⼆级标题5',prop:'value10'},
]},
{label:'⼀级标题2',prop:'value11'},
],
接收到后端传过来的title列表后,在template中渲染
ps:我的表头嵌套最多三层,所以直接这样写了,需要⽆限嵌套表头的童鞋⾃⾏百度吧有很多
<el-table
:data="tableData">
<el-table-column v-for="(v,idx) in tableHeader":key="idx"//tableHeader为后端传过来的title列表
:label="v.label":prop="v.prop":width="v.width" align="center">
<el-table-column
v-for="(j,i) in v.item"
:key="i"
:prop="j.prop"
:label="j.label"
:width="j.width" align="center">
<el-table-column
element表格横向滚动条
v-for="(m,n) in j.item"
:key="n"
:prop="m.prop"
:label="m.label"
:width="m.width" align="center">
</el-table-column>
</el-table-column>
</el-table-column>
</el-table>
2.合并单元格
因为表格中的数据可能相邻⼏⾏中的前⼏列内容是⼀样的,所以需要合并⾏
<el-table
:data="tableData"
:span-method="arraySpanMethod">//添加此⽅法
<el-table-column v-for="(v,idx) in tableHeader":key="idx"
:label="v.label":prop="v.prop":width="v.width" align="center"> <el-table-column
v-for="(j,i) in v.item"
:key="i"
:prop="j.prop"
:label="j.label"
:width="j.width" align="center">
<el-table-column
v-for="(m,n) in j.item"
:key="n"
:prop="m.prop"
:label="m.label"
:width="m.width" align="center">
</el-table-column>
</el-table-column>
</el-table-column>
</el-table>
spanArr:[],//需要合并⾏的个数
position:0
}
}
}
//获取列表数据
getList(page){
this.$axios.post('------URL-----').then(res =>{
this.tableData = res.data.data.data;//接收列表数据
});
},
//获得数据相同的⾏数
rowspan(){
//每次调⽤清空数据
this.spanArr=[];
this.position=0
this.tableData.forEach((item,index)=>{
if( index ===0){
this.spanArr.push(1);
this.position =0;
}else{
if(this.tableData[index].id ===this.tableData[index-1].id ){
this.spanArr[this.position]+=1;
this.spanArr.push(0);
}else{
this.spanArr.push(1);
this.position = index;
}
}
})
},
//合并单元格
arraySpanMethod({ row, column, rowIndex, columnIndex }){//表格合并⾏
if(columnIndex <=9){//我项⽬中需要前9项的⾏合并
const _row =this.spanArr[rowIndex];//需要合并多少⾏
const _col = _row >0?1:0;
return{
rowspan: _row,
colspan: _col
}
}
},
3.⾃适应列宽
百度所知elementui是暂不⽀持根据内容⾃适应列宽的,fit属性并没有⽤
titleList:[],//调⽤接⼝接收到的title列表
tableHeader:[],//渲染的列表,已经加上width属性
}
}
},
methods:{
//获取列表数据
getList(page){
this.$axios.post('------URL-----').then(res =>{
this.tableData = res.data.data.data;//接收列表数据
this.titleList = res.data.data.title;//接收列表数据
this.tableHeader =AllItem(this.titleList,this.tableData)//参数:title列表数据列表
});
},
//获取每列数据,通过计算加上width属性
getAllItem(head,data){
const _this =this
head.forEach(item =>{
if(item.item){//递归,判断是否为最后⼀级标题
_AllItem(item.item,data)
}else{
const arr = data.map(x => x[item.value])// 获取每⼀列的所有数据
arr.push(item.label)// 把每列的表头也加进去算
item.width = _MaxLength(arr)+50// 每列内容最⼤的宽度 + 表格的内间距
return item
}
})
return head
},
//使⽤span标签包裹内容,然后计算span的宽度 width: px
getTextWidth(str){
let width =0;
let html = ateElement('span');
html.innerText = str;
html.className ='getTextWidth';
document.querySelector('body').appendChild(html);
width = document.querySelector('.getTextWidth').offsetWidth;
document.querySelector('.getTextWidth').remove();
return width;
},
}
4.固定表格底部横向滚动条
因为内容过多,当想看表格最后⼏项内容时,需要把右侧滚动条滑到底部才能看到横向滚动条
<el-table
:data="tableData"
:
height="table_height"//给表格添加该属性
:span-method="arraySpanMethod">
</el-table>
mounted(){//在mounted中获取窗⼝的⾼,动态计算表格的⾼
const that =this;
that.table_height=document.body.clientHeight-280//该处减去了头部底部的⾼度,可按⾃⼰需求修改
that.table_height=document.body.clientHeight-280
};
},
总体代码
<template>
<el-table
:data="tableData"
:span-method="arraySpanMethod">
<el-table-column v-for="(v,idx) in tableHeader":key="idx"
:label="v.label":prop="v.prop":width="v.width" align="center">
<el-table-column
v-for="(j,i) in v.item"
:key="i"
:prop="j.prop"
:label="j.label"
:
width="j.width" align="center">
<el-table-column
v-for="(m,n) in j.item"
:key="n"
:prop="m.prop"
:label="m.label"
:width="m.width" align="center">
</el-table-column>
</el-table-column>
</el-table-column>
</el-table>
</template>
export default{
data(){
return{
tableData :[],
titleList:[],//调⽤接⼝接收到的title列表
tableHeader:[],//渲染的列表,已经加上width属性
spanArr:[],
position:0,
}
}
},
mounted(){//在mounted中获取窗⼝的⾼,动态计算表格的⾼
const that =this;
that.table_height=document.body.clientHeight-280//该处减去了头部底部的⾼度,可按⾃⼰需求修改 size=function(){
that.table_height=document.body.clientHeight-280
};
},
methods:{
//获取列表数据
getList(page){
this.$axios.post('------URL-----').then(res =>{
this.tableData = res.data.data.data;//接收列表数据
this.titleList = res.data.data.title;//接收列表数据
this.tableHeader =AllItem(this.titleList,this.tableData)//参数:title列表数据列表
});
},
//获得数据相同的⾏数
rowspan(){
//每次调⽤清空数据
this.spanArr=[];
this.position=0
this.tableData.forEach((item,index)=>{
if( index ===0){
this.spanArr.push(1);
this.position =0;
}else{
if(this.tableData[index].id ===this.tableData[index-1].id ){
this.spanArr[this.position]+=1;
this.spanArr.push(0);
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论