Vue 固定頭 固定列 點擊表頭可排序的表格組件
更新時間:2016年11月25日 17:10:16 作者:web前端小白
這篇文章主要介紹了Vue 固定頭 固定列 點擊表頭可排序的表格組件的相關資料,需要的朋友可以參考下
原理是將原table的指定行,指定列clone一份放在其上
實現(xiàn)代碼如下:
<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);
//判斷是否出現(xiàn)縱向滾動條,若出現(xiàn),高度減去滾動條寬度 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;
//判斷是否出現(xiàn)橫向滾動條,若出現(xiàn),高度減去滾動條高度 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{
// 接收父組件傳過來的參數(shù)
props: ['tableRows', 'gridColumns', 'thead', 'store', 'height', 'singleData'],
// 監(jiān)控
watch: {
'tableRows': function (val) {
var self = this
// 明星店鋪頁面時動態(tài)調整店鋪名所在列的寬度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 = ['品類', '產品種類', '均價', '銷量', '銷量環(huán)比', '銷量占比', '銷額(萬元)', '銷額環(huán)比', '銷額占比', '評論總數(shù)', '好評率']
}
}
以上所述是小編給大家介紹的Vue 固定頭 固定列 點擊表頭可排序的表格組件,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網站的支持!
您可能感興趣的文章:
- vue+element-ui動態(tài)生成多級表頭的方法
- vue elementUI table 自定義表頭和行合并的實例代碼
- vue element-ui table組件動態(tài)生成表頭和數(shù)據(jù)并修改單元格格式 父子組件通信
- Vue+elementui 實現(xiàn)復雜表頭和動態(tài)增加列的二維表格功能
- Vue+Element自定義縱向表格表頭教程
- Vue多種方法實現(xiàn)表頭和首列固定的示例代碼
- vue element 中的table動態(tài)渲染實現(xiàn)(動態(tài)表頭)
- vue el-table實現(xiàn)自定義表頭
- vue實現(xiàn)element表格里表頭信息提示功能(推薦)
- vue+elementui實現(xiàn)表格多級表頭效果
相關文章
vue3動態(tài)路由刷新出現(xiàn)空白頁的原因與最優(yōu)解
頁面刷新白屏其實是因為vuex引起的,由于刷新頁面vuex數(shù)據(jù)會丟失,這篇文章主要給大家介紹了關于vue3動態(tài)路由刷新出現(xiàn)空白頁的原因與最優(yōu)解的相關資料,需要的朋友可以參考下2023-11-11
ElementUI中el-form組件的rules參數(shù)舉例詳解
Form組件提供了表單驗證的功能,只需要通過rules屬性傳入約定的驗證規(guī)則,并將Form-Item的prop屬性設置為需校驗的字段名即可,下面這篇文章主要給大家介紹了關于ElementUI中el-form組件的rules參數(shù)的相關資料,需要的朋友可以參考下2023-10-10
vue開發(fā)runtime core中的虛擬節(jié)點示例詳解
這篇文章主要為大家介紹了vue開發(fā)runtime core中的虛擬節(jié)點示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-11-11

