ant desing vue table 實現(xiàn)可伸縮列的完整例子
完美解決ant-design-vue table 可伸縮列問題,實現(xiàn)在固定列,多級表頭情況下的伸縮列
這個東西本來以為手到擒來,因為在官網(wǎng)中已經(jīng)給出了例子,但是果然還是不能太信任官方,官方給出來的只能是最基礎(chǔ)的,然后我們正常的使用場景往往要復雜很多,比如固定列, 比如固定表頭,比如自帶checkbox列,比如多級表頭的情況。要想滿足這些情況往往需要自行開發(fā)。
1.首先蔣官方的例子copy下來,居然拖不動。
對照了一下官方,css居然都不一樣,于是增加了第一個改動
因為style內(nèi)聯(lián)樣式自帶了 translate屬性,所以直接去掉right:0;只留left -5.height設(shè)置100%就可以。
.resize-table-th {
position: relative;
.table-draggable-handle {
height: 100% !important;
bottom: 0;
left: -5px !important;
cursor: col-resize;
touch-action: none;
position: absolute;
}
}
2.這回可以看到每次拖拽后translate屬性實時在變化,但是單元格并沒有變寬移動。
于是又是檢查了元素,發(fā)現(xiàn)th的width在變化,但是colGroup的width屬性沒有變。于是開啟了尋找對應的colGroup的子元素col之旅,最后找到了,然后就是一頓操作在draging的時候同時修改了 colGroup的col的width屬性。這樣就可以跟著變化了。
3.接下來我發(fā)現(xiàn)在固定列和固定表頭的情況下拉伸會出現(xiàn)bug。
查看代碼發(fā)現(xiàn)當為固定列或者固定表頭的情況下實際上thead和tbody是在不同的 table上,這時候就需要找到所有的colGroup測col,改變width。這樣就處理了固定表頭的拉伸。但是固定列的情況還是需要另外設(shè)置css ,找到table-fixed-left重新設(shè)置寬度。
下面是一些代碼
根據(jù)當前的th,判斷th是父元素的第幾個孩子節(jié)點,對應到colGroup的第幾個col節(jié)點
const loopDom = ss => {
if (ss.previousSibling !== null) {
thDomIndex++;
loopDom(ss.previousSibling);
}
};
重新設(shè)置固定列的寬度(只處理了左浮動)
function resetFixedColumns(width) {
const fixedHead = document.querySelector(".ant-table-fixed-left .ant-table-header");
const fixedBody = document.querySelector(".ant-table-fixed-left .ant-table-body-outer .ant-table-fixed");
if (fixedHead) {
fixedHead.style.width = width + "px";
fixedBody.style.width = width + "px";
}
}
解決多級表頭伸縮列問題
遞歸遍歷數(shù)組,獲取寬度
getDraggingMap(tbCols, draggingMap) {
tbCols.forEach(col => {
if (col.children) {
this.getDraggingMap(col.children, draggingMap);
} else {
const key = col.dataIndex || col.key; //這兒要求表格數(shù)據(jù)中要有這兩個屬性
draggingMap[key] = col.width || 0;
}
});
},
遞歸遍歷數(shù)組,獲取當前列(這個遞歸真的很煩,不知道你們寫遞歸是什么感受)
// 處理多級表頭
getRenderCoL(key, tbCols) {
let result = "";
this._.forEach(tbCols, item => {
if (item.children) {
result = this.getRenderCoL(key, item.children);
return !result;
} else {
const k = item.dataIndex || item.key;
if (k === key) {
result = item;
return false;
}
}
});
return result;
}
遞歸遍歷數(shù)組, 獲取多級表頭操作列索引(同樣難以忍受的遞歸,開始少了最后一個renturn 一直跑不對,遞歸的陰影面積正無窮)
const loopDom = (cols, col) => {
let tag = true;
this._.forEach(cols, co => {
if (co.dataIndex == col.dataIndex) {
thDomIndex++;
tag = false;
return tag;
}
if (co.children) {
tag = loopDom(co.children, col);
return tag;
} else {
thDomIndex++;
}
});
return tag;
};
下面是完整代碼
這是一個js文件,通過mixin的方式引入table主文件, table 添加
:components="drag(columnKeys)"
//mixins/tableDragResize.js
import Vue from "vue";
import VueDraggableResizable from "vue-draggable-resizable";
Vue.component("vue-draggable-resizable", VueDraggableResizable);
export default {
data() {
return {
maxLevel: 1
};
},
methods: {
drag(columns) {
return {
header: {
cell: this.initDrag(columns)
}
};
},
/**
* @param { 表格columns } tbCols
*/
initDrag(tbCols) {
let draggingMap = {};
this.getDraggingMap(tbCols, draggingMap, 1);
let draggingState = Vue.observable(draggingMap);
return (h, props, children) => {
let thDomIndex = 0;
const { key, ...restProps } = props;
let col = {};
// 處理多級表頭
col = this.getRenderCoL(key, tbCols);
if (!col || !col.width) {
//這兒要求表格數(shù)據(jù)中要有寬width屬性,若是沒有是不會執(zhí)行下面的拖拽的
return <th {...restProps}>{children}</th>;
}
const onDrag = x => {
col.width = Math.max(x, 1);
draggingState[key] = col.width;
thDomIndex = 0;
loopDom(tbCols, col);
if (!this.attrBute.isCheck) {
thDomIndex--;
}
let colgroup = document.querySelectorAll("colgroup");
colgroup.forEach(Element => {
let childCol = Element.children;
if (childCol[thDomIndex]) childCol[thDomIndex].style.width = col.width + "px";
});
this.resetFixedColumns(col.width);
};
const loopDom = (cols, col) => {
let tag = true;
this._.forEach(cols, co => {
if (co.dataIndex == col.dataIndex) {
thDomIndex++;
tag = false;
return tag;
}
if (co.children) {
tag = loopDom(co.children, col);
return tag;
} else {
thDomIndex++;
}
});
return tag;
};
const onDragstop = () => {};
return (
<th {...restProps} width={draggingState[key]} class="resize-table-th" dataIndex={col.key}>
{children}
<vue-draggable-resizable
key={col.dataIndex || col.key}
class="table-draggable-handle"
w={20}
h={this.getResizableHandler(col)}
x={draggingState[key]}
z={100}
axis="x"
draggable={true}
resizable={false}
onDragging={onDrag}
onDragstop={onDragstop}
></vue-draggable-resizable>
</th>
);
};
},
getResizableHandler(col) {
// let baseH = thDom.getBoundingClientRect().height;
let size = this.cellsize ? this.cellsize : this.attrBute.cellsize;
let baseH = size == "middle" ? 47 : size == "small" ? 39 : 55;
if (col.isEndNode) return baseH * col.nodeLevel;
else if (col.leafNode && col.nodeLevel < this.maxLevel) {
return baseH * this.maxLevel;
} else return baseH;
},
resetFixedColumns(width) {
const fixedHead = document.querySelector(".ant-table-fixed-left .ant-table-header");
const fixedBody = document.querySelector(".ant-table-fixed-left .ant-table-body-outer .ant-table-fixed");
if (fixedHead) {
fixedHead.style.width = width + "px";
fixedBody.style.width = width + "px";
}
},
getDraggingMap(tbCols, draggingMap, nodeLevel) {
tbCols.forEach((col, index) => {
col.nodeLevel = nodeLevel;
col.isEndNode = index == tbCols.length - 1;
this.maxLevel = Math.max(this.maxLevel, nodeLevel);
if (col.children) {
col.leafNode = false;
this.getDraggingMap(col.children, draggingMap, nodeLevel + 1);
} else {
col.leafNode = true;
const key = col.dataIndex || col.key; //這兒要求表格數(shù)據(jù)中要有這兩個屬性
draggingMap[key] = col.width || 0;
}
});
},
getRenderCoL(key, tbCols) {
let result = "";
this._.forEach(tbCols, item => {
if (item.children) {
result = this.getRenderCoL(key, item.children);
return !result;
} else {
const k = item.dataIndex || item.key;
if (k === key) {
result = item;
return false;
}
}
});
return result;
}
}
};
后記 完美解決多級表頭的伸縮列 修改原getDraggingMap方法,增加nodeLevel 層級, isEndNode是否是蓋層級下最后一個節(jié)點, 以及this.maxLevel 記錄最大層級
getDraggingMap(tbCols, draggingMap, nodeLevel) {
tbCols.forEach((col, index) => {
col.nodeLevel = nodeLevel;
col.isEndNode = index == tbCols.length - 1;
this.maxLevel = Math.max(this.maxLevel, nodeLevel);
if (col.children) {
col.leafNode = false;
this.getDraggingMap(col.children, draggingMap, nodeLevel + 1);
} else {
col.leafNode = true;
const key = col.dataIndex || col.key; //這兒要求表格數(shù)據(jù)中要有這兩個屬性
draggingMap[key] = col.width || 0;
}
});
},
增加處理 table-draggable-handle的高度方法
看圖

可拖拽區(qū)域為紅色區(qū)域,為了達到這個效果,需要以下處理
首先去除css 中height :100%;
然后在render時 設(shè)置組件高度如下
h={this.getResizableHandler(col)}
size 是表格尺寸
getResizableHandler(col) {
// let baseH = thDom.getBoundingClientRect().height;
let size = this.cellsize ? this.cellsize : this.attrBute.cellsize;
let baseH = size == "middle" ? 47 : size == "small" ? 39 : 55;
if (col.isEndNode) return baseH * col.nodeLevel;
else if (col.leafNode && col.nodeLevel < this.maxLevel) {
return baseH * this.maxLevel;
} else return baseH;
},
完結(jié)
以上就是ant desing vue table 實現(xiàn)可伸縮列的詳細內(nèi)容,更多關(guān)于ant desing vue table 可伸縮列的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
vue中watch和computed的區(qū)別與使用方法
這篇文章主要給大家介紹了關(guān)于vue中watch和computed的區(qū)別與使用方法的相關(guān)資料,文中通過實例代碼結(jié)束的非常詳細,對大家學習或者使用Vue具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧2020-08-08
vue網(wǎng)站優(yōu)化實戰(zhàn)之秒開網(wǎng)頁
最近在搭建自己的博客,前端采用Vue技術(shù),發(fā)現(xiàn)首頁加載速度非常之慢,常常達到10S左右,遂開始優(yōu)化之旅,這篇文章主要給大家介紹了關(guān)于vue網(wǎng)站優(yōu)化實戰(zhàn)之秒開網(wǎng)頁的相關(guān)資料,需要的朋友可以參考下2022-08-08
vue?循環(huán)動態(tài)設(shè)置ref并獲取$refs方式
這篇文章主要介紹了vue?循環(huán)動態(tài)設(shè)置ref并獲取$refs方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-01-01
vue集成高德地圖amap-jsapi-loader的實現(xiàn)
本文主要介紹了vue集成高德地圖amap-jsapi-loader的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-06-06
Vue的watch和computed方法的使用及區(qū)別介紹
Vue的watch屬性可以用來監(jiān)聽data屬性中數(shù)據(jù)的變化。這篇文章主要介紹了Vue的watch和computed方法的使用及區(qū)別,需要的朋友可以參考下2018-09-09

