antdesingvuetable实现可伸缩列的完整例⼦
完美解决ant-design-vue table 可伸缩列问题,实现在固定列,多级表头情况下的伸缩列
这个东西本来以为⼿到擒来,因为在官⽹中已经给出了例⼦,但是果然还是不能太信任官⽅,官⽅给出来的只能是最基础的,然后我们正常的使⽤场景往往要复杂很多,⽐如固定列,⽐如固定表头,⽐如⾃带checkbox列,⽐如多级表头的情况。要想满⾜这些情况往往需要⾃⾏开发。
1.⾸先蒋官⽅的例⼦copy下来,居然拖不动。
对照了⼀下官⽅,css居然都不⼀样,于是增加了第⼀个改动
因为style内联样式⾃带了 translate属性,所以直接去掉right:0;只留left -5.height设置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属性实时在变化,但是单元格并没有变宽移动。
于是⼜是检查了元素,发现th的width在变化,但是colGroup的width属性没有变。于是开启了寻对应的colGroup的⼦元素col之旅,最后到了,然后就是⼀顿操作在draging的时候同时修改了 colGroup的col的width属性。这样就可以跟着变化了。
3.接下来我发现在固定列和固定表头的情况下拉伸会出现bug。
查看代码发现当为固定列或者固定表头的情况下实际上thead和tbody是在不同的 table上,这时候就需要到所有的colGroup测col,改变width。这样就处理了固定表头的拉伸。但是固定列的情况还是需要另外设置css ,到table-fixed-left重新设置宽度。
下⾯是⼀些代码
根据当前的th,判断th是⽗元素的第⼏个孩⼦节点,对应到colGroup的第⼏个col节点
const loopDom = ss => {
if (ss.previousSibling !== null) {
thDomIndex++;
loopDom(ss.previousSibling);
}
};
重新设置固定列的宽度(只处理了左浮动)
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";
}
}
解决多级表头伸缩列问题
递归遍历数组,获取宽度
getDraggingMap(tbCols, draggingMap) {
tbCols.forEach(col => {
if (col.children) {
} else {
const key = col.dataIndex || col.key; //这⼉要求表格数据中要有这两个属性
draggingMap[key] = col.width || 0;
}
});
},
递归遍历数组,获取当前列(这个递归真的很烦,不知道你们写递归是什么感受)
// 处理多级表头
getRenderCoL(key, tbCols) {
let result = "";
this._.forEach(tbCols, item => {
if (item.children) {
result = RenderCoL(key, item.children);
return !result;
} else {
const k = item.dataIndex || item.key;
if (k === key) {
result = item;
return false;
}
}
});
return result;
}
递归遍历数组,获取多级表头操作列索引(同样难以忍受的递归,开始少了最后⼀个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";
Vueponent("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 = {};
let draggingState = Vue.observable(draggingMap);
return (h, props, children) => {
let thDomIndex = 0;
const { key, ...restProps } = props;
let col = {};
// 处理多级表头
col = RenderCoL(key, tbCols);
if (!col || !col.width) {
//这⼉要求表格数据中要有宽width属性,若是没有是不会执⾏下⾯的拖拽的
return <th {...restProps}>{children}</th>;
}
nodeselectorconst 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";
});
};
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={ResizableHandler(col)}
x={draggingState[key]}
z={100}
axis="x"
draggable={true}
resizable={false}
onDragging={onDrag}
onDragstop={onDragstop}
></vue-draggable-resizable>
</th>
)
;
};
},
getResizableHandler(col) {
// let baseH = BoundingClientRect().height;
let size = llsize ? llsize : llsize;
let baseH = size == "middle" ? 47 : size == "small" ? 39 : 55;
if (col.isEndNode) return baseH * deLevel;
else if (col.leafNode && deLevel < 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.isEndNode = index == tbCols.length - 1;
this.maxLevel = Math.max(this.maxLevel, nodeLevel);
if (col.children) {
col.leafNode = false;
} else {
col.leafNode = true;
const key = col.dataIndex || col.key; //这⼉要求表格数据中要有这两个属性
draggingMap[key] = col.width || 0;
}
});
},
getRenderCoL(key, tbCols) {
let result = "";
this._.forEach(tbCols, item => {
if (item.children) {
result = RenderCoL(key, item.children);
return !result;
} else {
const k = item.dataIndex || item.key;
if (k === key) {
result = item;
return false;
}
}
});
return result;
}
}
};
后记完美解决多级表头的伸缩列修改原getDraggingMap⽅法,增加nodeLevel 层级, isEndNode是否是盖层级下最后⼀个节点,以及this.maxLevel 记录最⼤层级
getDraggingMap(tbCols, draggingMap, nodeLevel) {
tbCols.forEach((col, index) => {
col.isEndNode = index == tbCols.length - 1;
this.maxLevel = Math.max(this.maxLevel, nodeLevel);
if (col.children) {
col.leafNode = false;
} else {
col.leafNode = true;
const key = col.dataIndex || col.key; //这⼉要求表格数据中要有这两个属性
draggingMap[key] = col.width || 0;
}
});
},
增加处理 table-draggable-handle的⾼度⽅法
看图
可拖拽区域为红⾊区域,为了达到这个效果,需要以下处理
⾸先去除css 中height :100%;
然后在render时设置组件⾼度如下
h={ResizableHandler(col)}
size 是表格尺⼨
getResizableHandler(col) {
/
/ let baseH = BoundingClientRect().height;
let size = llsize ? llsize : llsize;
let baseH = size == "middle" ? 47 : size == "small" ? 39 : 55;
if (col.isEndNode) return baseH * deLevel;
else if (col.leafNode && deLevel < this.maxLevel) {
return baseH * this.maxLevel;
} else return baseH;
},
完结
以上就是ant desing vue table 实现可伸缩列的详细内容,更多关于ant desing vue table 可伸缩列的资料请关注其它相关⽂章!

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。