当前位置: 移动技术网 > IT编程>脚本编程>vue.js > Vue 固定头 固定列 点击表头可排序的表格组件

Vue 固定头 固定列 点击表头可排序的表格组件

2018年05月11日  | 移动技术网IT编程  | 我要评论

原理是将原table的指定行,指定列clone一份放在其上

实现代码如下:

<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 = ''; 
 var hashead = ''; 
 window.settimeout = function(fref, mdelay) { 
  if(typeof fref == 'function') { 
   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 || '#ffffff', 
   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 + '_div_head'; 
  var strtbid = _.id + '_tb_header'; 
  var div = document.createelement('div'); 
  div.id = strdivid; 
  div.style.csstext = 'position:absolute;overflow:hidden;z-index:' + (_.config.zindex + 1) + ';'; 
  div.innerhtml = '<table id="' + strtbid + '" cellpadding="0" cellspacing="0" style="background:' + _.config.background + ';"></table>'; 
  _.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) + 'px'; 
  _.tbhead.style.textalign = _.obj.style.textalign; 
  _.tbhead.style.width = _.obj.offsetwidth + 'px'; 
  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 + '_div_left'; 
  var strtbid = _.id + '_tb_left'; 
  var div = document.createelement('div'); 
  div.id = strdivid; 
  div.style.csstext = 'position:absolute;overflow:hidden;z-index:' + _.config.zindex + ';box-shadow: #dddddd 2px 0px 2px;width: 2rem;'; 
  div.innerhtml = '<table id=' + 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 
  var sw = _.obj.offsetwidth > _.box.offsetwidth ? 0 : 0; 
  _.divleft.style.height = (_.box.offsetheight - sw) + 'px'; 
  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 + '_div_top_left'; 
  var strtbid = _.id + '_tb_top_left'; 
  var div = document.createelement('div'); 
  div.id = strdivid; 
  div.style.csstext = 'position:absolute;overflow:hidden;z-index:' + (_.config.zindex + 2) + ';box-shadow: #dddddd 2px 0px 2px;width: 2rem;'; 
  div.innerhtml = '<table id="' + strtbid + '" cellpadding="0" cellspacing="0" style="background:' + _.config.background + ';"></table>'; 
  _.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: ['tablerows', 'gridcolumns', 'thead', 'store', 'height', 'singledata'], 
  // 监控 
  watch: { 
   'tablerows': function (val) { 
    var self = this 
    // 明星店铺页面时动态调整店铺名所在列的宽度s 
    if (self.store) { 
     document.queryselectorall('table td:nth-child(3)')[0].style.width = 3 + 'rem' 
     document.queryselectorall('table th:nth-child(3)')[0].style.width = 3 + 'rem' 
    } 
    var length = 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_left td')[0].style.width = 2 + 'rem' 
     var tbobj = document.getelementbyid('ofix1_tb_header') 
     tbobj.addeventlistener('click',function (event) { 
      if(event.target.tagname === 'th'){ 
       self.sortby(event.target.innertext, event) 
      } 
     }) 
    }, 101) 
   } 
  }, 
  data: function() { 
   var sortorders = {} 
   this.gridcolumns.foreach(function (key) { 
    sortorders[key] = 1 
   }) 
   return { 
    sortkey: '', 
    filterurl: './static/img/indus/filter1.png', 
    sortorders: sortorders 
   } 
  }, 
  methods: { 
   sortbykey: function (a, b) { 
    return parsefloat(a[this.sortkey]) - parsefloat(b[this.sortkey]) 
    console.log('11111111111') 
   }, 
   sortby: function (key, event) { 
    // 每一次排序之前所有的图片重置 
    var imgdom = document.queryselectorall('#ofix1_tb_header th img') 
    for (var x = 0; x < imgdom.length; x++) { 
     imgdom[x].setattribute('src', './static/img/indus/filter1.png') 
    } 
    // 排序 
    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('img')[0].setattribute('src', './static/img/indus/filter2.png') 
    } else { 
     event.target.getelementsbytagname('img')[0].setattribute('src', './static/img/indus/filter3.png') 
    } 
    // 排序时同步改变左边第一列的内容 
    settimeout(function(){ 
     var tddom = document.queryselectorall('#tbtest1 tr td:nth-child(1)') 
     var tddomleft = document.queryselectorall('#ofix1_tb_left td') 
     for (var y = 0; y < tddom.length; y++) { 
      tddomleft[y].innerhtml = tddom[y].innerhtml 
     } 
    },0) 
   } 
  }, 
  filters: { 
   numberfilter: function (value) { 
    if (value == 0) { 
     return '0' 
    } else if (!value) { 
     return '/' 
    } else { 
     return value 
    } 
   } 
  }, 
  components: { 
  }, 
  ready: function() { 
   var ofix1 = new ofixedtable('ofix1', document.getelementbyid('tbtest1'), { 
    rows: 1, 
    cols: 1 
   }) 
  }, 
  created () { 
  } 
 } 
</script> 
<style lang="scss" 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> 

父组件调用实例:

<template> 
   <table-locked :table-rows="tabledata" :grid-columns="gridcolumns" :thead="thead" :height="height"> 
   </table-locked> 
</template> 
import tablelocked from '../../common/tablelocked.vue' 
export default{ 
  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 固定头 固定列 点击表头可排序的表格组件,希望对大家有所帮助

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网