elementui table html,elementUI中的elTable实现原理分析

elementUI中的elTable实现原理图

a29d134789db2254efeaed45e44e0b31.png

上图是我们使用element table组件的一个常见场景,顶部固定,左侧列固定,右侧列固定,甚至底部行固定。这些特性对于展现数据,报表等是非常友好的一种用户体验。

今天我们不谈elTable的使用,今天我们来谈一谈elTable功能实现的原理。

c55a0f2990c2b922f7d5be0501c3949b.png

第一步,我们就需要正常的展现这个table表格,td中的宽度用户设定多少就是多少,没设定就自动宽度。

第二步,通过js操作dom,获取到这个table中,每一行的高度,每一列的宽度。

第三步,实现table功能的的布局。

12e70c54352a8dec6c0b2c9fce89e17b.png

这样,我们table布局就实现了。简单点实现的话,每一个块内都放置整个table,然后定义定高或者定宽。超出部分不展示。

第四步,滚动条跟随滚动,如果有纵向滚动条,那么添加滚动事件,在滚动时,左侧,右侧固定列偏移对应的滚动值。横向滚动条类似。

第五步,gutter,比如出现纵向滚动条时,内容去的table宽度小了一个滚动条的宽度,那么头部固定表格需要添加一个空td,设置宽度为滚动条宽度,才能与内容区table对齐。计算方法就是内容去table外层div的offsetWidth - clientWidth得到滚动条的宽度。

d1cccb9d58782cce3d9798c01b612859.png

gutter就是上图红框区域。

综上所述,elementUI的elTable实现原理就是上面这几步骤。

用途

Vue中JSX使用绘制报表,此文章处就是一个使用的地方,对于复杂报表,不管是elementUI table,还是vxe-table都显得无能为力。这时候我们就可以使用更加灵活强大的render函数来实现功能了。

但是如果客户需要表头固定,那么我们就需要用到上面的知识了。

690ee02deea539d5fd97436e36ae8a4a.png

运用上述知识,我们就可以轻松实现表头固定的功能。

export default{

props:{

lists:{

type:Array,

default:()=>{

return [];

}

},

tps:{

type:Array,

default:()=>{

return ['银川','吴忠','石嘴山','中卫','宁东','固原'];

}

},

//前五名加背景色

five:{

type:Boolean,

default:false

}

},

data(){

return {

gutter:0,

}

},

computed:{

dobleList(){

let arr = [];

for(let i =0 ;i

arr.push(this.lists[i]);

arr.push(this.lists[i]);

}

return arr;

}

},

mounted(){

setTimeout(()=>{

this.$nextTick(()=>{

this.calGutter();

});

},500);

},

methods:{

calGutter(){

let cht = this.$refs.cont.clientHeight;

let tht = this.$refs.tbs.offsetHeight;

let owd = this.$refs.cont.offsetWidth;

let cwd = this.$refs.cont.clientWidth;

if(tht<=cht){

this.gutter = 0;

}else{

this.gutter =( owd - cwd -2) + 'px'

}

},

gettClass(it,k){

let cstr = '';

if(it.value&&it.value.length>k){

if(it.value[k].zbpm==1){

cstr = 'rp-first';

} else if (this.five){

switch(it.value[k].zbpm){

case 2:

case 3:

case 4:

case 5: cstr = 'rp-two';

}

}

}

return cstr;

}

},

render(){

return (

  

{

this.tps.map(it=>{

return 

{it}

})

}

{

this.gutter!=0?

:""

}

{

this.dobleList.map((it,i)=>{

if(i%2==0){

return (

{

i/2==1?

专业管理:""

}

{ it.dwmc }得分

{

this.tps.map((t,k)=>{

return 

{

it.value&&it.value.length>k?it.value[k].zbdf:""

}

})

}

{

this.gutter>0?

:""

}

)

}else{

return (

排名

{

this.tps.map((t,k)=>{

return 

{

it.value&&it.value.length>k?it.value[k].zbpm:""

}

})

}

{

this.gutter!=0?

:""

}

)

}

})

}

  

{

this.tps.map(it=>{

return 

{it}

})

}

{

this.dobleList.map((it,i)=>{

if(i%2==0){

return (

{

i/2==1?

专业管理:""

}

{ it.dwmc }得分

{

this.tps.map((t,k)=>{

return 

{

it.value&&it.value.length>k?it.value[k].zbdf:""

}

})

}

)

}else{

return (

排名

{

this.tps.map((t,k)=>{

return 

{

it.value&&it.value.length>k?it.value[k].zbpm:""

}

})

}

)

}

})

}

)

}

}

完整表头固定代码如上,我是采用了第二种方式,表头区域渲染了整个table的备份,只是设置了固定高度截图表头部分。算是偷懒的实现吧。/* 报表样式 */

.rp-header{background:#e1e1e1;}

.rp-table th,.rp-table td{text-align:center;line-height: 28px;font-size:13px;color:#0E0E0E;}

.rp-noscroll{height:29px;overflow:hidden;top:0;left:0;right:0;position:absolute;z-index: 2;}

.rp-table td.rp-first{background:#00A187;color:#fff;font-weight:bolder;}

.rp-table td.rp-two{background:#31E4C7;color:#fff;}

样式只要通过absolute定位就可以实现了。

希望此文章对你能有所帮助。