Perfect solution to the scalable column problem of ant-design-vue table, realizing scalable columns in fixed columns and multi-level headersI thought this thing would be easy to use, because examples have been given on the official website. However, we still cannot trust the official website too much. The official website can only provide the most basic ones, and our normal usage scenarios are often much more complicated, such as fixed columns, fixed headers, built-in checkbox columns, and multi-level headers. To meet these situations, it is often necessary to develop your own. 1. First of all, I copied Chiang’s official example, but it couldn’t be dragged out. After comparing with the official one, I found that the CSS was different, so I added the first change. Because the style inline style has its own translate attribute, I directly removed right: 0 and only left -5. Set the height to 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. This time you can see that the translate attribute changes in real time after each drag, but the cell does not become wider or move. So I checked the elements again and found that the width of th was changing, but the width attribute of colGroup did not change. So I started looking for the corresponding colGroup child element col. Finally I found it, and then I modified the width attribute of colGroup's col while dragging. This way you can follow the changes. 3. Next, I found that stretching would cause a bug when the columns and headers were fixed. Looking at the code, I found that when it is a fixed column or a fixed header, thead and tbody are actually on different tables. At this time, you need to find all colGroups to measure col and change the width. This handles the stretching of the fixed header. However, in the case of fixed columns, you still need to set CSS separately, find table-fixed-left and reset the width. Here is some codeAccording to the current th, determine which child node th is the parent element, corresponding to which col node of colGroup const loopDom = ss => { if (ss.previousSibling !== null) { thDomIndex++; loopDom(ss.previousSibling); } }; Reset the width of fixed columns (only handles left float) 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"; } } Solve the problem of multi-level header expansion columnRecursively traverse the array and get the width getDraggingMap(tbCols, draggingMap) { tbCols.forEach(col => { if (col.children) { this.getDraggingMap(col.children, draggingMap); } else { const key = col.dataIndex || col.key; //The table data must have these two attributes draggingMap[key] = col.width || 0; } }); }, Recursively traverse the array and get the current column (this recursion is really annoying, I don’t know how you feel about writing recursion) // Processing multi-level headers 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; } Recursively traverse the array to obtain the index of the multi-level header operation column (the recursion is also unbearable. At the beginning, the last renturn is missing and it keeps running wrong. The shadow area of the recursion is infinite) 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; }; Here is the complete codeThis is a js file, which introduces the table main file through mixin. Table adds :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 { table 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 = {}; // Processing multi-level headers col = this.getRenderCoL(key, tbCols); if (!col || !col.width) { //Here the table data must have a width attribute. If not, the following dragging will not be executed. 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; //The table data must have these two attributes 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; } } }; Postscript Perfect solution to the expansion column of multi-level table header Modify the original getDraggingMap method, add nodeLevel level, isEndNode is the last node under the cover level, and this.maxLevel records the maximum level 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; //The table data must have these two attributes draggingMap[key] = col.width || 0; } }); }, Add a method to handle the height of table-draggable-handle View image The draggable area is the red area. To achieve this effect, the following processing is required First remove the height in the CSS: 100%; h = {this.getResizableHandler(col)} size is the table 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; }, end The above is the details of ant design vue table to achieve scalable columns. For more information about ant design vue table scalable columns, please pay attention to other related articles on 123WORDPRESS.COM! You may also be interested in:
|
<<: How to install mysql via yum on centos7
>>: How to detect whether a file is damaged using Apache Tika
Text Shadow text-shadow: horizontal offset vertic...
When to install If you use the protoc command and...
1. Click Terminal below in IDEA and enter mvn cle...
Table of contents 1. Repeated declaration 1.1 var...
Because the Raspberry Pi is based on ARM architec...
Code Knowledge Points 1. Combine fullpage.js to a...
Preface: The previous article described several c...
HTML operation principle: 1. Local operation: ope...
How to achieve internationalization in React? The...
illustrate: Using mysqldump –all-databases will e...
Environmental requirements: IP hostname 192.168.1...
1. Check the synchronization status of A and B da...
CentOS official website address https://www.cento...
Result:Implementation Code html <nav class=&qu...
CSS3 -- Adding shadows (using box shadows) CSS3 -...