Vue 固定头 固定列 点击表头可排序的表格组件
原理是将原table的指定行,指定列clone一份放在其上
实现代码如下:
<template>
<div>
<divid="divBox1":style="{height:height}">
<tableid="tbTest1"cellpadding="0"cellspacing="0"style="text-align:center;background:rgba(244,249,255,0.4);">
<tr>
<thv-for="iteminthead"@click="sortBy(item)">
{{item}}<imgstyle="width:0.16rem;height:0.20rem;margin-left:4px;":src="filterUrl"alt=""v-if="$index!=0"data-img="{{filterUrl}}">
</th>
</tr>
<trv-for="rowintableRows|orderBysortBykeysortOrders[sortKey]">
<tdstyle="overflow:hidden;white-space:nowrap;"v-for="itemingridColumns"v-html="row[item]|numberFilter":id="$parent.$index">
</td>
</tr>
</table>
</div>
</div>
</template>
<script>
/*eslint-disable*/
varofixed_table_st=window.setTimeout;
varhasLeft='';
varhasHead='';
window.setTimeout=function(fRef,mDelay){
if(typeoffRef=='function'){
varargu=Array.prototype.slice.call(arguments,2);
varf=(function(){
fRef.apply(null,argu);
});
returnofixed_table_st(f,mDelay);
}
returnofixed_table_st(fRef,mDelay);
};
functionoFixedTable(id,obj,_cfg){
this.id=id;
this.obj=obj;
this.box=this.obj.parentNode;
this.config={
fixHead:_cfg.fixHead||true,
rows:_cfg.rows||1,
cols:_cfg.cols||0,
background:_cfg.background||'#ffffff',
zindex:_cfg.zindex||10
};
window.setTimeout(this._fixTable,100,this);
}
oFixedTable.prototype._fixTable=function(_){
if(_.obj.rows.length<=0){
returnfalse;
}
varhasLeft=_.buildLeft();
varhasHead=_.buildHead();
_.box.onscroll=function(){
if(_.divHead!=null){
_.divHead.scrollLeft=this.scrollLeft;
}
if(_.divLeft!=null){
_.divLeft.scrollTop=this.scrollTop;
}
};
if(hasHead&&hasLeft){
_.buildTopLeft();
}
};
oFixedTable.prototype.buildHead=function(){
console.log(2222222222222222222)
var_=this;
varstrDivId=_.id+'_div_head';
varstrTbId=_.id+'_tb_header';
vardiv=document.createElement('div');
div.id=strDivId;
div.style.cssText='position:absolute;overflow:hidden;z-index:'+(_.config.zindex+1)+';';
div.innerHTML='<tableid="'+strTbId+'"cellpadding="0"cellspacing="0"style="background:'+_.config.background+';"></table>';
_.box.insertBefore(div,_.obj);
_.divHead=div;
_.tbHead=document.getElementById(strTbId);
//判断是否出现纵向滚动条,若出现,高度减去滚动条宽度16px
varsw=_.obj.offsetHeight>_.box.offsetHeight?0:0;
_.divHead.style.width=(_.box.offsetWidth-sw)+'px';
_.tbHead.style.textAlign=_.obj.style.textAlign;
_.tbHead.style.width=_.obj.offsetWidth+'px';
varhasHead=false;
if(_.config.fixHead&&_.obj.tHead!=null){
vartHead=_.obj.tHead;
_.tbHead.appendChild(tHead.cloneNode(true));
hasHead=true;
}else{
for(vari=0;i<_.config.rows;i++){
varrow=_.obj.rows[i];
if(row!=null){
_.tbHead.appendChild(row.cloneNode(true));
hasHead=true;
}
}
}
returnhasHead;
};
oFixedTable.prototype.buildLeft=function(){
var_=this;
if(_.config.cols<=0){
returnfalse;
}
varstrDivId=_.id+'_div_left';
varstrTbId=_.id+'_tb_left';
vardiv=document.createElement('div');
div.id=strDivId;
div.style.cssText='position:absolute;overflow:hidden;z-index:'+_.config.zindex+';box-shadow:#dddddd2px0px2px;width:2rem;';
div.innerHTML='<tableid='+strTbId+'cellpadding="0"cellspacing="0"style="background:'+_.config.background+';width:2rem;"></table>';
_.box.insertBefore(div,_.obj);
_.divLeft=div;
_.tbLeft=document.getElementById(strTbId);
_.tbLeft.style.textAlign=_.obj.style.textAlign;
//判断是否出现横向滚动条,若出现,高度减去滚动条高度16px
varsw=_.obj.offsetWidth>_.box.offsetWidth?0:0;
_.divLeft.style.height=(_.box.offsetHeight-sw)+'px';
varhasLeft=false;
for(vari=0,rows=_.obj.rows.length;i<rows;i++){
varrow=_.tbLeft.insertRow(_.tbLeft.rows.length);
row.style.cssText=_.obj.rows[i].style.cssText;
for(varj=0;j<_.config.cols;j++){
varcell=_.obj.rows[i].cells[j];
if(cell!=null){
row.appendChild(cell.cloneNode(true));
cell.style.cssText=_.obj.rows[i].cells[j].style.cssText;
hasLeft=true;
}
}
}
returnhasLeft;
};
oFixedTable.prototype.buildTopLeft=function(){
var_=this;
varstrDivId=_.id+'_div_top_left';
varstrTbId=_.id+'_tb_top_left';
vardiv=document.createElement('div');
div.id=strDivId;
div.style.cssText='position:absolute;overflow:hidden;z-index:'+(_.config.zindex+2)+';box-shadow:#dddddd2px0px2px;width:2rem;';
div.innerHTML='<tableid="'+strTbId+'"cellpadding="0"cellspacing="0"style="background:'+_.config.background+';"></table>';
_.box.insertBefore(div,_.obj);
vartbTopLeft=document.getElementById(strTbId);
tbTopLeft.style.textAlign=_.obj.style.textAlign;
for(vari=0;i<_.config.rows;i++){
varrow=tbTopLeft.insertRow(tbTopLeft.rows.length);
row.style.cssText=_.obj.rows[i].style.cssText;
for(varj=0;j<_.config.cols;j++){
varcell=_.obj.rows[i].cells[j];
if(cell!=null){
row.appendChild(cell.cloneNode(true));
cell.style.cssText=_.obj.rows[i].cells[j].style.cssText;
hasLeft=true;
}
}
}
};
exportdefault{
//接收父组件传过来的参数
props:['tableRows','gridColumns','thead','store','height','singleData'],
//监控
watch:{
'tableRows':function(val){
varself=this
//明星店铺页面时动态调整店铺名所在列的宽度s
if(self.store){
document.querySelectorAll('tabletd:nth-child(3)')[0].style.width=3+'rem'
document.querySelectorAll('tableth:nth-child(3)')[0].style.width=3+'rem'
}
varlength=self.gridColumns.length
document.getElementById('tbTest1').style.width=2*length+'rem'
setTimeout(function(){
if(self.singleData){
document.getElementById('ofix1_tb_left').classList.add('ofix1_tb_left')
}
document.querySelectorAll('#ofix1_tb_lefttd')[0].style.width=2+'rem'
vartbObj=document.getElementById('ofix1_tb_header')
tbObj.addEventListener('click',function(event){
if(event.target.tagName==='TH'){
self.sortBy(event.target.innerText,event)
}
})
},101)
}
},
data:function(){
varsortOrders={}
this.gridColumns.forEach(function(key){
sortOrders[key]=1
})
return{
sortKey:'',
filterUrl:'./static/img/indus/filter1.png',
sortOrders:sortOrders
}
},
methods:{
sortBykey:function(a,b){
returnparseFloat(a[this.sortKey])-parseFloat(b[this.sortKey])
console.log('11111111111')
},
sortBy:function(key,event){
//每一次排序之前所有的图片重置
varimgDom=document.querySelectorAll('#ofix1_tb_headerthimg')
for(varx=0;x<imgDom.length;x++){
imgDom[x].setAttribute('src','./static/img/indus/filter1.png')
}
//排序
varactiveTheadIndex=0
for(vari=0;i<this.thead.length;i++){
if(this.thead[i]===key){
activeTheadIndex=i
}
}
this.sortKey=this.gridColumns[activeTheadIndex]
this.sortOrders[this.gridColumns[activeTheadIndex]]=this.sortOrders[this.gridColumns[activeTheadIndex]]*-1
//排序时同步改变标识图片
if(this.sortOrders[this.gridColumns[activeTheadIndex]]>0){
event.target.getElementsByTagName('img')[0].setAttribute('src','./static/img/indus/filter2.png')
}else{
event.target.getElementsByTagName('img')[0].setAttribute('src','./static/img/indus/filter3.png')
}
//排序时同步改变左边第一列的内容
setTimeout(function(){
vartdDom=document.querySelectorAll('#tbTest1trtd:nth-child(1)')
vartdDomLeft=document.querySelectorAll('#ofix1_tb_lefttd')
for(vary=0;y<tdDom.length;y++){
tdDomLeft[y].innerHTML=tdDom[y].innerHTML
}
},0)
}
},
filters:{
numberFilter:function(value){
if(value==0){
return'0'
}elseif(!value){
return'/'
}else{
returnvalue
}
}
},
components:{
},
ready:function(){
varofix1=newoFixedTable('ofix1',document.getElementById('tbTest1'),{
rows:1,
cols:1
})
},
created(){
}
}
</script>
<stylelang="scss"scoped>
#divBox1{
overflow:auto;
width:100%;
font-size:0.28rem;
}
#ofix1_div_left{
box-shadow:#dddddd2px0px2px;
width:2rem;
}
table{
table-layout:fixed;
}
tabletd,
tableth{
width:2rem;
line-height:1rem;
height:1rem;
padding:0;
color:#999999;
overflow:hidden;
white-space:nowrap;
/*vertical-align:middle;*/
}
tableth{
background:rgba(188,219,255,0.4);
color:#999;
font-size:.28rem;
font-weight:normal;
}
tableth:nth-child(1){
box-shadow:#dddddd2px0px0px;
}
.ofix1_tb_lefttrtd:nth-child(1){
/*display:inline-block;*/
text-align:left;
}
#ofix1_div_top_left{
box-shadow:#dddddd2px0px2px;
}
#tbTest1trtd:nth-child(1){
box-shadow:#dddddd2px0px0px;
}
#tbheadertd{
background:#fff;
}
</style>
父组件调用实例:
<template>
<table-locked:table-rows="tableData":grid-columns="gridColumns":thead="thead":height="height">
</table-locked>
</template>
importTableLockedfrom'../../common/TableLocked.vue'
exportdefault{
components:{TableLocked},
data(){
data.gridColumns=['brand','product_count','averagePrice','sales','huang_sale_per','sale_per','sales_amount','huang_sale_amount_per','sales_amount_per','score_num','scort_good_per']
data.thead=['品类','产品种类','均价','销量','销量环比','销量占比','销额(万元)','销额环比','销额占比','评论总数','好评率']
}
}
以上所述是小编给大家介绍的Vue固定头固定列点击表头可排序的表格组件,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!