Home  >  Article  >  php教程  >  Vue fixed header, fixed column, table component that can be sorted by clicking on the header

Vue fixed header, fixed column, table component that can be sorted by clicking on the header

高洛峰
高洛峰Original
2016-12-05 11:16:511576browse

The principle is to clone the specified rows and columns of the original table and place it on top of it

The implementation code is as follows:

<template> 
 <div> 
  <div id="divBox1" :style="{height:height}"> 
   <table id="tbTest1" cellpadding="0" cellspacing="0" style="text-align:center;background:rgba(244,249,255,0.4);"> 
    <tr> 
     <th v-for="item in thead" @click="sortBy(item)"> 
      {{item}}<img style="width:0.16rem;height:0.20rem;margin-left:4px;" :src="filterUrl" alt="" v-if="$index!=0" data-img="{{filterUrl}}"> 
     </th> 
    </tr> 
    <tr v-for="row in tableRows | orderBy sortBykey sortOrders[sortKey]"> 
     <td style="overflow:hidden;white-space:nowrap;" v-for="item in gridColumns" v-html="row[item] | numberFilter" :id="$parent.$index"> 
     </td> 
    </tr> 
   </table> 
  </div> 
 </div> 
</template> 
<script> 
 /*eslint-disable*/
 var ofixed_table_st = window.setTimeout; 
 var hasLeft = &#39;&#39;; 
 var hasHead = &#39;&#39;; 
 window.setTimeout = function(fRef, mDelay) { 
  if(typeof fRef == &#39;function&#39;) { 
   var argu = Array.prototype.slice.call(arguments, 2); 
   var f = (function() { 
    fRef.apply(null, argu); 
   }); 
   return ofixed_table_st(f, mDelay); 
  } 
  return ofixed_table_st(fRef, mDelay); 
 }; 
 function oFixedTable(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 || &#39;#ffffff&#39;, 
   zindex: _cfg.zindex || 10 
  }; 
  window.setTimeout(this._fixTable, 100, this); 
 } 
 oFixedTable.prototype._fixTable = function(_) { 
  if(_.obj.rows.length <= 0) { 
   return false; 
  } 
  var hasLeft = _.buildLeft(); 
  var hasHead = _.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; 
  var strDivId = _.id + &#39;_div_head&#39;; 
  var strTbId = _.id + &#39;_tb_header&#39;; 
  var div = document.createElement(&#39;div&#39;); 
  div.id = strDivId; 
  div.style.cssText = &#39;position:absolute;overflow:hidden;z-index:&#39; + (_.config.zindex + 1) + &#39;;&#39;; 
  div.innerHTML = &#39;<table id="&#39; + strTbId + &#39;" cellpadding="0" cellspacing="0" style="background:&#39; + _.config.background + &#39;;"></table>&#39;; 
  _.box.insertBefore(div, _.obj); 
  _.divHead = div; 
  _.tbHead = document.getElementById(strTbId); 
  //判断是否出现纵向滚动条,若出现,高度减去滚动条宽度 16px 
  var sw = _.obj.offsetHeight > _.box.offsetHeight ? 0 : 0; 
  _.divHead.style.width = (_.box.offsetWidth - sw) + &#39;px&#39;; 
  _.tbHead.style.textAlign = _.obj.style.textAlign; 
  _.tbHead.style.width = _.obj.offsetWidth + &#39;px&#39;; 
  var hasHead = false; 
  if(_.config.fixHead && _.obj.tHead != null) { 
   var tHead = _.obj.tHead; 
   _.tbHead.appendChild(tHead.cloneNode(true)); 
   hasHead = true; 
  } else { 
   for(var i = 0; i < _.config.rows; i++) { 
    var row = _.obj.rows[i]; 
    if(row != null) { 
     _.tbHead.appendChild(row.cloneNode(true)); 
     hasHead = true; 
    } 
   } 
  } 
  return hasHead; 
 }; 
 oFixedTable.prototype.buildLeft = function() { 
  var _ = this; 
  if(_.config.cols <= 0) { 
   return false; 
  } 
  var strDivId = _.id + &#39;_div_left&#39;; 
  var strTbId = _.id + &#39;_tb_left&#39;; 
  var div = document.createElement(&#39;div&#39;); 
  div.id = strDivId; 
  div.style.cssText = &#39;position:absolute;overflow:hidden;z-index:&#39; + _.config.zindex + &#39;;box-shadow: #dddddd 2px 0px 2px;width: 2rem;&#39;; 
  div.innerHTML = &#39;<table id=&#39; + strTbId + &#39; cellpadding="0" cellspacing="0" style="background:&#39; + _.config.background + &#39;;width: 2rem;"></table>&#39;; 
  _.box.insertBefore(div, _.obj); 
  _.divLeft = div; 
  _.tbLeft = document.getElementById(strTbId); 
  _.tbLeft.style.textAlign = _.obj.style.textAlign; 
  //判断是否出现横向滚动条,若出现,高度减去滚动条高度 16px 
  var sw = _.obj.offsetWidth > _.box.offsetWidth ? 0 : 0; 
  _.divLeft.style.height = (_.box.offsetHeight - sw) + &#39;px&#39;; 
  var hasLeft = false; 
  for(var i = 0, rows = _.obj.rows.length; i < rows; i++) { 
   var row = _.tbLeft.insertRow(_.tbLeft.rows.length); 
   row.style.cssText = _.obj.rows[i].style.cssText; 
   for(var j = 0; j < _.config.cols; j++) { 
    var cell = _.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; 
    } 
   } 
  } 
  return hasLeft; 
 }; 
 oFixedTable.prototype.buildTopLeft = function() { 
  var _ = this; 
  var strDivId = _.id + &#39;_div_top_left&#39;; 
  var strTbId = _.id + &#39;_tb_top_left&#39;; 
  var div = document.createElement(&#39;div&#39;); 
  div.id = strDivId; 
  div.style.cssText = &#39;position:absolute;overflow:hidden;z-index:&#39; + (_.config.zindex + 2) + &#39;;box-shadow: #dddddd 2px 0px 2px;width: 2rem;&#39;; 
  div.innerHTML = &#39;<table id="&#39; + strTbId + &#39;" cellpadding="0" cellspacing="0" style="background:&#39; + _.config.background + &#39;;"></table>&#39;; 
  _.box.insertBefore(div, _.obj); 
  var tbTopLeft = document.getElementById(strTbId); 
  tbTopLeft.style.textAlign = _.obj.style.textAlign; 
  for(var i = 0; i < _.config.rows; i++) { 
   var row = tbTopLeft.insertRow(tbTopLeft.rows.length); 
   row.style.cssText = _.obj.rows[i].style.cssText; 
   for(var j = 0; j < _.config.cols; j++) { 
    var cell = _.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; 
    } 
   } 
  } 
 }; 
 export default{ 
  // 接收父组件传过来的参数 
  props: [&#39;tableRows&#39;, &#39;gridColumns&#39;, &#39;thead&#39;, &#39;store&#39;, &#39;height&#39;, &#39;singleData&#39;], 
  // 监控 
  watch: { 
   &#39;tableRows&#39;: function (val) { 
    var self = this
    // 明星店铺页面时动态调整店铺名所在列的宽度s 
    if (self.store) { 
     document.querySelectorAll(&#39;table td:nth-child(3)&#39;)[0].style.width = 3 + &#39;rem&#39;
     document.querySelectorAll(&#39;table th:nth-child(3)&#39;)[0].style.width = 3 + &#39;rem&#39;
    } 
    var length = self.gridColumns.length 
    document.getElementById(&#39;tbTest1&#39;).style.width = 2 * length + &#39;rem&#39;
    setTimeout(function () { 
     if (self.singleData) { 
      document.getElementById(&#39;ofix1_tb_left&#39;).classList.add(&#39;ofix1_tb_left&#39;) 
     } 
     document.querySelectorAll(&#39;#ofix1_tb_left td&#39;)[0].style.width = 2 + &#39;rem&#39;
     var tbObj = document.getElementById(&#39;ofix1_tb_header&#39;) 
     tbObj.addEventListener(&#39;click&#39;,function (event) { 
      if(event.target.tagName === &#39;TH&#39;){ 
       self.sortBy(event.target.innerText, event) 
      } 
     }) 
    }, 101) 
   } 
  }, 
  data: function() { 
   var sortOrders = {} 
   this.gridColumns.forEach(function (key) { 
    sortOrders[key] = 1 
   }) 
   return { 
    sortKey: &#39;&#39;, 
    filterUrl: &#39;./static/img/indus/filter1.png&#39;, 
    sortOrders: sortOrders 
   } 
  }, 
  methods: { 
   sortBykey: function (a, b) { 
    return parseFloat(a[this.sortKey]) - parseFloat(b[this.sortKey]) 
    console.log(&#39;11111111111&#39;) 
   }, 
   sortBy: function (key, event) { 
    // 每一次排序之前所有的图片重置 
    var imgDom = document.querySelectorAll(&#39;#ofix1_tb_header th img&#39;) 
    for (var x = 0; x < imgDom.length; x++) { 
     imgDom[x].setAttribute(&#39;src&#39;, &#39;./static/img/indus/filter1.png&#39;) 
    } 
    // 排序 
    var activeTheadIndex = 0 
    for (var i = 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(&#39;img&#39;)[0].setAttribute(&#39;src&#39;, &#39;./static/img/indus/filter2.png&#39;) 
    } else { 
     event.target.getElementsByTagName(&#39;img&#39;)[0].setAttribute(&#39;src&#39;, &#39;./static/img/indus/filter3.png&#39;) 
    } 
    // 排序时同步改变左边第一列的内容 
    setTimeout(function(){ 
     var tdDom = document.querySelectorAll(&#39;#tbTest1 tr td:nth-child(1)&#39;) 
     var tdDomLeft = document.querySelectorAll(&#39;#ofix1_tb_left td&#39;) 
     for (var y = 0; y < tdDom.length; y++) { 
      tdDomLeft[y].innerHTML = tdDom[y].innerHTML 
     } 
    },0) 
   } 
  }, 
  filters: { 
   numberFilter: function (value) { 
    if (value == 0) { 
     return &#39;0&#39;
    } else if (!value) { 
     return &#39;/&#39;
    } else { 
     return value 
    } 
   } 
  }, 
  components: { 
  }, 
  ready: function() { 
   var ofix1 = new oFixedTable(&#39;ofix1&#39;, document.getElementById(&#39;tbTest1&#39;), { 
    rows: 1, 
    cols: 1 
   }) 
  }, 
  created () { 
  } 
 } 
</script> 
<style scoped>
 #divBox1{ 
  overflow:auto; 
  width:100%; 
  font-size: 0.28rem; 
 }
 #ofix1_div_left{ 
  box-shadow: #dddddd 2px 0px 2px; 
  width: 2rem; 
 } 
 table { 
  table-layout : fixed; 
 } 
 table td, 
 table th { 
  width: 2rem; 
  line-height: 1rem; 
  height: 1rem; 
  padding: 0; 
  color: #999999; 
  overflow: hidden; 
  white-space: nowrap; 
  /*vertical-align: middle;*/
 } 
 table th{ 
  background: rgba(188,219,255,0.4); 
  color: #999; 
  font-size: .28rem; 
  font-weight: normal; 
 } 
 table th:nth-child(1){ 
  box-shadow: #dddddd 2px 0px 0px; 
 } 
 .ofix1_tb_left tr td:nth-child(1){ 
  /*display: inline-block;*/
  text-align: left; 
 }
 #ofix1_div_top_left{ 
  box-shadow: #dddddd 2px 0px 2px; 
 }
 #tbTest1 tr td:nth-child(1){ 
  box-shadow: #dddddd 2px 0px 0px; 
 }
 #tbheader td { 
  background: #fff; 
 } 
</style>

Parent component calling example:

<template> 
   <table-locked :table-rows="tableData" :grid-columns="gridColumns" :thead="thead" :height="height"> 
   </table-locked> 
</template> 
import TableLocked from &#39;../../common/TableLocked.vue&#39;
export default{ 
  components: {TableLocked}, 
  data () { 
    data.gridColumns = [&#39;brand&#39;, &#39;product_count&#39;, &#39;averagePrice&#39;, &#39;sales&#39;, &#39;huang_sale_per&#39;, &#39;sale_per&#39;, &#39;sales_amount&#39;, &#39;huang_sale_amount_per&#39;, &#39;sales_amount_per&#39;, &#39;score_num&#39;, &#39;scort_good_per&#39;] 
   data.thead = [&#39;品类&#39;, &#39;产品种类&#39;, &#39;均价&#39;, &#39;销量&#39;, &#39;销量环比&#39;, &#39;销量占比&#39;, &#39;销额(万元)&#39;, &#39;销额环比&#39;, &#39;销额占比&#39;, &#39;评论总数&#39;, &#39;好评率&#39;] 
  } 
}


Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn