Skip to content

Commit

Permalink
支持分组列宽拖拽
Browse files Browse the repository at this point in the history
  • Loading branch information
xuliangzhan committed Jan 13, 2025
1 parent b14fa48 commit 49114b6
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 32 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "vxe-table",
"version": "4.10.6-beta.2",
"version": "4.10.6-beta.4",
"description": "一个基于 vue 的 PC 端表格组件,支持增删改查、虚拟树、拖拽排序,懒加载、快捷菜单、数据校验、树形结构、打印、导入导出、自定义模板、渲染器、JSON 配置式...",
"scripts": {
"update": "npm install --legacy-peer-deps",
Expand Down
3 changes: 2 additions & 1 deletion packages/table/src/body.ts
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ export default defineComponent({
)
}
}
const isLastColumn = $columnIndex === columns.length - 1
const isAutoCellWidth = !column.resizeWidth && (column.minWidth === 'auto' || column.width === 'auto')

let isPreLoadStatus = false
Expand All @@ -356,7 +357,7 @@ export default defineComponent({
[`col--${cellAlign}`]: cellAlign,
[`col--vertical-${verticalAlign}`]: verticalAlign,
[`col--${type}`]: type,
'col--last': $columnIndex === columns.length - 1,
'col--last': isLastColumn,
'col--tree-node': treeNode,
'col--edit': isEdit,
'col--ellipsis': hasEllipsis,
Expand Down
3 changes: 2 additions & 1 deletion packages/table/src/footer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ export default defineComponent({
attrs.colspan = colspan
}
}
const isLastColumn = $columnIndex === tableColumn.length - 1
const isAutoCellWidth = !column.resizeWidth && (column.minWidth === 'auto' || column.width === 'auto')

let isPreLoadStatus = false
Expand All @@ -164,7 +165,7 @@ export default defineComponent({
class: ['vxe-footer--column', column.id, {
[`col--${footAlign}`]: footAlign,
[`col--${type}`]: type,
'col--last': $columnIndex === tableColumn.length - 1,
'col--last': isLastColumn,
'fixed--width': !isAutoCellWidth,
'fixed--hidden': fixedHiddenColumn,
'col--ellipsis': hasEllipsis,
Expand Down
48 changes: 29 additions & 19 deletions packages/table/src/header.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { defineComponent, TransitionGroup, h, ref, Ref, PropType, inject, nextTick, watch, onMounted, onUnmounted } from 'vue'
import XEUtils from 'xe-utils'
import { VxeUI } from '../../ui'
import { convertHeaderColumnToRows, getColReMinWidth } from './util'
import { convertHeaderColumnToRows, getColReMinWidth, getRefElem } from './util'
import { hasClass, getOffsetPos, addClass, removeClass } from '../../ui/src/dom'

import type { VxeTablePrivateMethods, VxeTableConstructor, VxeTableMethods, VxeTableDefines, VxeColumnPropTypes } from '../../../types'
Expand All @@ -26,7 +26,7 @@ export default defineComponent({
const $xeTable = inject('$xeTable', {} as VxeTableConstructor & VxeTableMethods & VxeTablePrivateMethods)

const { xID, props: tableProps, reactData: tableReactData, internalData: tableInternalData } = $xeTable
const { refElem: tableRefElem, refTableBody, refLeftContainer, refRightContainer, refCellResizeBar, refCellResizeTip } = $xeTable.getRefMaps()
const { refElem: tableRefElem, refLeftContainer, refRightContainer, refCellResizeBar, refCellResizeTip } = $xeTable.getRefMaps()
const { computeColumnOpts, computeColumnDragOpts, computeResizableOpts } = $xeTable.getComputeMaps()

const headerColumn = ref([] as VxeTableDefines.ColumnInfo[][])
Expand All @@ -47,9 +47,8 @@ export default defineComponent({
const resizeMousedownEvent = (evnt: MouseEvent, params: VxeTableDefines.CellRenderHeaderParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }) => {
const { column } = params
const { fixedType } = props
const { visibleColumn } = tableInternalData
const { elemStore, visibleColumn } = tableInternalData
const resizableOpts = computeResizableOpts.value
const tableBody = refTableBody.value
const tableEl = tableRefElem.value
const leftContainerElem = refLeftContainer.value
const rightContainerElem = refRightContainer.value
Expand All @@ -58,10 +57,19 @@ export default defineComponent({
const { clientX: dragClientX } = evnt
const wrapperElem = refElem.value
const dragBtnElem = evnt.target as HTMLDivElement
let resizeColumn = column
if (column.children && column.children.length) {
XEUtils.eachTree(column.children, childColumn => {
resizeColumn = childColumn
})
}
const cell = dragBtnElem.parentNode as HTMLTableCellElement
const cellParams = Object.assign(params, { cell })
let dragLeft = 0
const tableBodyElem = tableBody.$el as HTMLDivElement
const bodyScrollElem = getRefElem(elemStore['main-body-scroll'])
if (!bodyScrollElem) {
return
}
const pos = getOffsetPos(dragBtnElem, wrapperElem)
const dragBtnWidth = dragBtnElem.clientWidth
const dragBtnOffsetWidth = Math.floor(dragBtnWidth / 2)
Expand Down Expand Up @@ -92,25 +100,25 @@ export default defineComponent({
}

// 处理拖动事件
const updateEvent = function (evnt: MouseEvent) {
const updateEvent = (evnt: MouseEvent) => {
evnt.stopPropagation()
evnt.preventDefault()
const offsetX = evnt.clientX - dragClientX
let left = dragPosLeft + offsetX
const scrollLeft = fixedType ? 0 : tableBodyElem.scrollLeft
const scrollLeft = fixedType ? 0 : bodyScrollElem.scrollLeft
if (isLeftFixed) {
// 左固定列(不允许超过右侧固定列、不允许超过右边距)
left = Math.min(left, (rightContainerElem ? rightContainerElem.offsetLeft : tableBodyElem.clientWidth) - fixedOffsetWidth - minInterval)
left = Math.min(left, (rightContainerElem ? rightContainerElem.offsetLeft : bodyScrollElem.clientWidth) - fixedOffsetWidth - minInterval)
} else if (isRightFixed) {
// 右侧固定列(不允许超过左侧固定列、不允许超过左边距)
dragMinLeft = (leftContainerElem ? leftContainerElem.clientWidth : 0) + fixedOffsetWidth + minInterval
left = Math.min(left, dragPosLeft + cell.clientWidth - minInterval)
} else {
dragMinLeft = Math.max(tableBodyElem.scrollLeft, dragMinLeft)
// left = Math.min(left, tableBodyElem.clientWidth + tableBodyElem.scrollLeft - 40)
dragMinLeft = Math.max(bodyScrollElem.scrollLeft, dragMinLeft)
// left = Math.min(left, bodyScrollElem.clientWidth + bodyScrollElem.scrollLeft - 40)
}
dragLeft = Math.max(left, dragMinLeft)
const resizeBarLeft = dragLeft - scrollLeft
const resizeBarLeft = Math.max(1, dragLeft - scrollLeft)
resizeBarElem.style.left = `${resizeBarLeft}px`
if (resizableOpts.showDragTip && resizeTipElem) {
const tableWidth = tableEl.clientWidth
Expand All @@ -120,13 +128,13 @@ export default defineComponent({
const resizeTipHeight = resizeTipElem.clientHeight
let resizeTipLeft = -resizeTipWidth
if (resizeBarLeft < resizeTipWidth + resizeBarWidth) {
resizeTipLeft = resizeTipWidth + resizeBarWidth - resizeBarLeft
resizeTipLeft = 0
} else if (resizeBarLeft > tableWidth) {
resizeTipLeft += tableWidth - resizeBarLeft
}
resizeTipElem.style.left = `${resizeTipLeft}px`
resizeTipElem.style.top = `${Math.min(tableEl.clientHeight - resizeTipHeight, Math.max(0, evnt.clientY - wrapperRect.y - resizeTipHeight / 2))}px`
resizeTipElem.textContent = getI18n('vxe.table.resizeColTip', [column.renderWidth + (isRightFixed ? dragPosLeft - dragLeft : dragLeft - dragPosLeft)])
resizeTipElem.textContent = getI18n('vxe.table.resizeColTip', [resizeColumn.renderWidth + (isRightFixed ? dragPosLeft - dragLeft : dragLeft - dragPosLeft)])
}
}

Expand All @@ -137,11 +145,11 @@ export default defineComponent({
document.onmouseup = function (evnt) {
document.onmousemove = domMousemove
document.onmouseup = domMouseup
const resizeWidth = column.renderWidth + (isRightFixed ? dragPosLeft - dragLeft : dragLeft - dragPosLeft)
column.resizeWidth = resizeWidth
const resizeWidth = resizeColumn.renderWidth + (isRightFixed ? dragPosLeft - dragLeft : dragLeft - dragPosLeft)
resizeColumn.resizeWidth = resizeWidth
if (resizableOpts.dragMode === 'fixed') {
visibleColumn.forEach(item => {
if (item.id !== column.id) {
if (item.id !== resizeColumn.id) {
if (!item.resizeWidth) {
item.resizeWidth = item.renderWidth
}
Expand Down Expand Up @@ -229,6 +237,8 @@ export default defineComponent({
thOns.onMouseup = $xeTable.handleHeaderCellDragMouseupEvent
}
}
const isLastColumn = $columnIndex === cols.length - 1
const showResizable = (XEUtils.isBoolean(column.resizable) ? column.resizable : (columnOpts.resizable || allResizable))
const isAutoCellWidth = !column.resizeWidth && (column.minWidth === 'auto' || column.width === 'auto')

let isPreLoadStatus = false
Expand All @@ -240,7 +250,7 @@ export default defineComponent({
class: ['vxe-header--column', colid, {
[`col--${headAlign}`]: headAlign,
[`col--${type}`]: type,
'col--last': $columnIndex === cols.length - 1,
'col--last': isLastColumn,
'col--fixed': column.fixed,
'col--group': isColGroup,
'col--ellipsis': hasEllipsis,
Expand Down Expand Up @@ -271,15 +281,15 @@ export default defineComponent({
/**
* 列宽拖动
*/
!fixedHiddenColumn && !isColGroup && (XEUtils.isBoolean(column.resizable) ? column.resizable : (columnOpts.resizable || allResizable))
!fixedHiddenColumn && showResizable
? h('div', {
class: ['vxe-resizable', {
'is--line': !border || border === 'none'
}],
onMousedown: (evnt: MouseEvent) => resizeMousedownEvent(evnt, params),
onDblclick: (evnt: MouseEvent) => $xeTable.handleResizeDblclickEvent(evnt, params)
})
: null
: renderEmptyElement($xeTable)
])
})
}
Expand Down
16 changes: 11 additions & 5 deletions packages/table/src/table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1192,7 +1192,7 @@ export default defineComponent({
}
fullColumnFieldData[field] = rest
} else {
if (storage || (columnOpts.drag && (isCrossDrag || isSelfToChildDrag))) {
if ((storage && !type) || (columnOpts.drag && (isCrossDrag || isSelfToChildDrag))) {
errLog('vxe.error.reqProp', [`${column.getTitle() || type || ''} -> column.field`])
}
}
Expand Down Expand Up @@ -6616,17 +6616,23 @@ export default defineComponent({
if (isDblclickAutoWidth && el) {
const { fullColumnIdData } = internalData
const { column } = params
const colid = column.id
let resizeColumn = column
if (column.children && column.children.length) {
XEUtils.eachTree(column.children, childColumn => {
resizeColumn = childColumn
})
}
const colid = resizeColumn.id
const colRest = fullColumnIdData[colid]
const dragBtnElem = evnt.target as HTMLDivElement
const cell = dragBtnElem.parentNode as HTMLTableCellElement
const cellParams = Object.assign(params, { cell })
const colMinWidth = getColReMinWidth(cellParams)
let resizeWidth = calcColumnAutoWidth(column, el)
let resizeWidth = calcColumnAutoWidth(resizeColumn, el)
if (colRest) {
resizeWidth = Math.max(resizeWidth, colRest.width)
}
column.resizeWidth = Math.max(colMinWidth, resizeWidth)
resizeColumn.resizeWidth = Math.max(colMinWidth, resizeWidth)
reactData._isResize = false
internalData._lastResizeTime = Date.now()
$xeTable.analyColumnWidth()
Expand Down Expand Up @@ -6860,7 +6866,7 @@ export default defineComponent({
vLen++
})

const isSelected = rootList.length > 0 && sLen >= vLen
const isSelected = vLen > 0 ? sLen >= vLen : sLen >= rootList.length
const halfSelect = !isSelected && (sLen >= 1 || hLen >= 1)

reactData.isAllSelected = isSelected
Expand Down
12 changes: 7 additions & 5 deletions styles/components/table.scss
Original file line number Diff line number Diff line change
Expand Up @@ -51,19 +51,21 @@
scrollbar-width: none;
}
.vxe-table--header-inner-wrapper,
.vxe-table--body-inner-wrapper,
.vxe-table--footer-inner-wrapper {
position: relative;
width: 100%;
height: 100% ;
height: 100%;
scrollbar-width: none;
}
.vxe-table--header-inner-wrapper,
.vxe-table--footer-inner-wrapper {
overflow-y: hidden;
overflow-x: scroll;
scrollbar-width: none;
}
.vxe-table--body-inner-wrapper {
width: 100% ;
height: 100% ;
overflow-y: scroll;
overflow-x: scroll;
scrollbar-width: none;
}

.vxe-loading--custom-wrapper {
Expand Down

0 comments on commit 49114b6

Please sign in to comment.