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固定头固定列点击表头可排序的表格组件,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!