diff --git a/.gitee/ISSUE_TEMPLATE/bug_report.yml b/.gitee/ISSUE_TEMPLATE/bug_report.yml
index ee0c6ab6df..e722d7f857 100644
--- a/.gitee/ISSUE_TEMPLATE/bug_report.yml
+++ b/.gitee/ISSUE_TEMPLATE/bug_report.yml
@@ -5,7 +5,7 @@ body:
- type: input
id: issue_link
attributes:
- label: "可复现的链接:"
+ label: "可复现的链接(必须为公开链接,仅包含能复现问题的示例代码):"
description: "一个最小化的重现示例能让我们精确地定位问题,从而快速解决问题。如何创建,点击 v3:[codesandbox](https://codesandbox.io/s/vue-template-916h0)、[jsfiddle](https://jsfiddle.net/86p7Ltny/)、[jsrun](https://jsrun.net/vIyKp/edit) 或 v4:[codesandbox](https://codesandbox.io/s/vxe-table-wentiyanshi-forked-54v2j)、[jsfiddle](https://jsfiddle.net/9qoghkbj/)、[jsrun](https://jsrun.net/K5IKp/edit),将代码示例编辑后保存。"
validations:
required: true
@@ -26,27 +26,27 @@ body:
id: issue_os_version
attributes:
label: "操作系统:"
- placeholder: "例如:window10"
+ placeholder: "例如:window11"
validations:
required: true
- type: input
id: issue_browser_version
attributes:
label: "浏览器版本:"
- placeholder: "例如:chrome 95.0.4638.69"
+ placeholder: "例如:chrome 133.0.6876.4"
validations:
required: true
- type: input
id: issue_vue_version
attributes:
label: "vue 版本:"
- placeholder: "例如:2.6.0"
+ placeholder: "例如:3.5.0"
validations:
required: true
- type: input
id: issue_vxe_version
attributes:
label: "vxe-table 版本:"
- placeholder: "例如:3.4.0"
+ placeholder: "例如:3.9.0"
validations:
required: true
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
index eea0f595b0..d349247693 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -5,7 +5,7 @@ body:
- type: input
id: issue_link
attributes:
- label: "可复现的链接(包含复现链接与示例代码):"
+ label: "可复现的链接(必须为公开链接,仅包含能复现问题的示例代码):"
description: "一个最小化的重现示例能让我们精确地定位问题,从而快速解决问题。"
validations:
required: true
diff --git a/examples/views/table/TableTest2.vue b/examples/views/table/TableTest2.vue
index 4a4ecf5743..6a82c9484b 100644
--- a/examples/views/table/TableTest2.vue
+++ b/examples/views/table/TableTest2.vue
@@ -14,6 +14,7 @@
id="bbbbb"
:row-config="{useKey: true,drag:true}"
:column-config="{useKey: true,drag: true}"
+ :column-drag-config="{isCrossDrag:true,isToChildDrag:true,isSelfToChildDrag:true}"
:custom-config="customConfig"
:loading="demo1.loading"
:import-config="{modes: importModes}"
@@ -25,10 +26,10 @@
@row-dragstart="rowDragstartEvent"
@row-dragover="rowDragoverEvent"
@row-dragend="rowDragendEvent">
-
-
-
-
+
+
+
+
{{ row.name }}
@@ -76,7 +77,8 @@ const exportModes = ref([
])
const customConfig = reactive({
- storage: true,
+ immediate: false,
+ // storage: true,
checkMethod ({ column }) {
return column.type !== 'seq'
},
diff --git a/examples/views/table/TableTest3.vue b/examples/views/table/TableTest3.vue
index f140cce6f4..70e76c0d8f 100644
--- a/examples/views/table/TableTest3.vue
+++ b/examples/views/table/TableTest3.vue
@@ -12,16 +12,17 @@
id="aaaa"
:row-config="{useKey: true}"
:column-config="{useKey: true}"
+ :column-drag-config="{isCrossDrag:true,isToChildDrag:true,isSelfToChildDrag:true}"
:print-config="{}"
:import-config="{}"
:export-config="{}"
- :custom-config="{mode: 'popup',storage:true}"
+ :custom-config="{mode: 'popup',immediate: false}"
:loading="demo1.loading"
:expand-config="{iconOpen: 'vxe-icon-question-circle-fill', iconClose: 'vxe-icon-question-circle-fill'}"
:checkbox-config="{labelField: 'id', highlight: true, range: true}"
:data="demo1.tableData">
-
-
+
+
@@ -30,8 +31,8 @@
-
-
+
+
('VxeDrawer')
const VxeUIButtonComponent = VxeUI.getComponent('VxeButton')
const VxeUINumberInputComponent = VxeUI.getComponent('VxeNumberInput')
- const VxeUITooltipComponent = VxeUI.getComponent('VxeTooltip')
const VxeUIRadioGroupComponent = VxeUI.getComponent('VxeRadioGroup')
const $xeTable = inject('$xeTable', {} as VxeTableConstructor & VxeTableMethods & VxeTablePrivateMethods)
- const { props: tableProps, reactData } = $xeTable
- const { computeCustomOpts, computeColumnOpts, computeIsMaxFixedColumn, computeResizableOpts } = $xeTable.getComputeMaps()
+ const { props: tableProps, reactData, internalData } = $xeTable
+ const { computeCustomOpts, computeColumnDragOpts, computeColumnOpts, computeIsMaxFixedColumn, computeResizableOpts } = $xeTable.getComputeMaps()
const refElem = ref() as Ref
const bodyElemRef = ref() as Ref
- const dragHintElemRef = ref() as Ref
+ const refDragLineElem = ref() as Ref
+ const refDragTipElem = ref() as Ref
const dragColumnRef = ref()
- let prevDropTrEl: any
+ let prevDragCol: VxeTableDefines.ColumnInfo | undefined
+ let prevDragToChild = false
+ let prevDragPos: any
const handleWrapperMouseenterEvent = (evnt: Event) => {
const { customStore } = props
@@ -56,6 +58,7 @@ export default defineComponent({
}
const confirmCustomEvent: VxeButtonEvents.Click = ({ $event }) => {
+ reactData.isCustomStatus = true
$xeTable.saveCustom()
$xeTable.closeCustom()
$xeTable.emitCustomEvent('confirm', $event)
@@ -116,6 +119,7 @@ export default defineComponent({
item.renderVisible = isChecked
item.halfVisible = false
})
+ reactData.isCustomStatus = true
$xeTable.handleCustom()
$xeTable.saveCustomStore('update:visible')
} else {
@@ -128,6 +132,19 @@ export default defineComponent({
$xeTable.checkCustomStatus()
}
+ const changeColumnWidth = (column: VxeTableDefines.ColumnInfo) => {
+ const customOpts = computeCustomOpts.value
+ if (customOpts.immediate) {
+ if (column.renderResizeWidth !== column.renderWidth) {
+ column.resizeWidth = column.renderResizeWidth
+ column.renderWidth = column.renderResizeWidth
+ reactData.isCustomStatus = true
+ $xeTable.handleCustom()
+ $xeTable.saveCustomStore('update:width')
+ }
+ }
+ }
+
const changeFixedOption = (column: VxeTableDefines.ColumnInfo, colFixed: VxeColumnPropTypes.Fixed) => {
const isMaxFixedColumn = computeIsMaxFixedColumn.value
const customOpts = computeCustomOpts.value
@@ -145,6 +162,7 @@ export default defineComponent({
})
}
}
+ reactData.isCustomStatus = true
$xeTable.handleCustom()
$xeTable.saveCustomStore('update:fixed')
} else {
@@ -166,130 +184,334 @@ export default defineComponent({
$xeTable.toggleCustomAllCheckbox()
}
+ const showDropTip = (evnt: DragEvent | MouseEvent, optEl: HTMLElement | null, showLine: boolean, dragPos: string) => {
+ const el = bodyElemRef.value
+ if (!el) {
+ return
+ }
+ const wrapperRect = el.getBoundingClientRect()
+ if (optEl) {
+ const dragLineEl = refDragLineElem.value
+ if (dragLineEl) {
+ if (showLine) {
+ const optRect = optEl.getBoundingClientRect()
+ dragLineEl.style.display = 'block'
+ dragLineEl.style.top = `${Math.max(1, optRect.y - wrapperRect.y)}px`
+ dragLineEl.style.height = `${optRect.height}px`
+ dragLineEl.style.width = `${optRect.width}px`
+ dragLineEl.setAttribute('drag-pos', dragPos)
+ dragLineEl.setAttribute('drag-to-child', prevDragToChild ? 'y' : 'n')
+ } else {
+ dragLineEl.style.display = ''
+ }
+ }
+ }
+ const dragTipEl = refDragTipElem.value
+ if (dragTipEl) {
+ dragTipEl.style.display = 'block'
+ dragTipEl.style.top = `${Math.min(el.clientHeight - el.scrollTop - dragTipEl.clientHeight, evnt.clientY - wrapperRect.y)}px`
+ dragTipEl.style.left = `${Math.min(el.clientWidth - el.scrollLeft - dragTipEl.clientWidth - 16, evnt.clientX - wrapperRect.x)}px`
+ dragTipEl.setAttribute('drag-status', showLine ? (prevDragToChild ? 'sub' : 'normal') : 'disabled')
+ }
+ }
+
+ const hideDropTip = () => {
+ const dragTipEl = refDragTipElem.value
+ const dragLineEl = refDragLineElem.value
+ if (dragTipEl) {
+ dragTipEl.style.display = ''
+ }
+ if (dragLineEl) {
+ dragLineEl.style.display = ''
+ }
+ }
+
const sortMousedownEvent = (evnt: DragEvent) => {
const btnEl = evnt.currentTarget as HTMLElement
- const tdEl = btnEl.parentNode as HTMLElement
- const trEl = tdEl.parentNode as HTMLElement
+ const cellEl = btnEl.parentElement as HTMLElement
+ const tdEl = cellEl.parentElement as HTMLElement
+ const trEl = tdEl.parentElement as HTMLElement
const colid = trEl.getAttribute('colid')
const column = $xeTable.getColumnById(colid)
trEl.draggable = true
dragColumnRef.value = column
addClass(trEl, 'active--drag-origin')
- updateDropHint(evnt)
}
const sortMouseupEvent = (evnt: MouseEvent) => {
const btnEl = evnt.currentTarget as HTMLElement
- const tdEl = btnEl.parentNode as HTMLElement
- const trEl = tdEl.parentNode as HTMLElement
- const dragHintEl = dragHintElemRef.value
+ const cellEl = btnEl.parentElement as HTMLElement
+ const tdEl = cellEl.parentElement as HTMLElement
+ const trEl = tdEl.parentElement as HTMLElement
+ hideDropTip()
trEl.draggable = false
dragColumnRef.value = null
removeClass(trEl, 'active--drag-origin')
- if (dragHintEl) {
- dragHintEl.style.display = ''
- }
}
const sortDragstartEvent = (evnt: DragEvent) => {
- const img = new Image()
if (evnt.dataTransfer) {
+ const img = new Image()
+ img.src = tpImg
evnt.dataTransfer.setDragImage(img, 0, 0)
}
}
const sortDragendEvent = (evnt: DragEvent) => {
+ const { mouseConfig } = tableProps
const { customColumnList } = reactData
+ const { collectColumn } = internalData
const customOpts = computeCustomOpts.value
+ const { immediate } = customOpts
const trEl = evnt.currentTarget as HTMLElement
- const dragHintEl = dragHintElemRef.value
- if (prevDropTrEl) {
+ const dragCol = dragColumnRef.value
+ const columnDragOpts = computeColumnDragOpts.value
+ const { isCrossDrag, isSelfToChildDrag, isToChildDrag, dragEndMethod } = columnDragOpts
+ const dragOffsetIndex = prevDragPos === 'bottom' ? 1 : 0
+ if (prevDragCol && dragCol) {
// 判断是否有拖动
- if (prevDropTrEl !== trEl) {
- const dragOffset = prevDropTrEl.getAttribute('drag-pos')
- const colid = trEl.getAttribute('colid')
- const column = $xeTable.getColumnById(colid)
- if (!column) {
- return
- }
- const cIndex = XEUtils.findIndexOf(customColumnList, item => item.id === column.id)
- const targetColid = prevDropTrEl.getAttribute('colid')
- const targetColumn = $xeTable.getColumnById(targetColid)
- if (!targetColumn) {
- return
- }
- // 移出源位置
- customColumnList.splice(cIndex, 1)
- const tcIndex = XEUtils.findIndexOf(customColumnList, item => item.id === targetColumn.id)
- // 插新位置
- customColumnList.splice(tcIndex + (dragOffset === 'bottom' ? 1 : 0), 0, column)
+ if (prevDragCol !== dragCol) {
+ const oldColumn = dragCol
+ const newColumn = prevDragCol
+ Promise.resolve(
+ dragEndMethod
+ ? dragEndMethod({
+ oldColumn,
+ newColumn,
+ dragPos: prevDragPos as any,
+ offsetIndex: dragOffsetIndex
+ })
+ : true
+ ).then((status) => {
+ if (!status) {
+ return
+ }
+
+ let oafIndex = -1
+ let nafIndex = -1
+
+ const oldAllMaps: Record = {}
+ XEUtils.eachTree([oldColumn], column => {
+ oldAllMaps[column.id] = column
+ })
+
+ let isSelfToChildStatus = false
+
+ // 只有实时拖拽支持跨层级
+ if (immediate) {
+ if (oldColumn.parentId && newColumn.parentId) {
+ // 子到子
+
+ if (!isCrossDrag) {
+ return
+ }
+ if (oldAllMaps[newColumn.id]) {
+ isSelfToChildStatus = true
+ if (!isSelfToChildDrag) {
+ if (VxeUI.modal) {
+ VxeUI.modal.message({
+ status: 'error',
+ content: getI18n('vxe.error.treeDragChild')
+ })
+ }
+ return
+ }
+ }
+ } else if (oldColumn.parentId) {
+ // 子到根
+
+ if (!isCrossDrag) {
+ return
+ }
+ } else if (newColumn.parentId) {
+ // 根到子
+
+ if (!isCrossDrag) {
+ return
+ }
+ if (oldAllMaps[newColumn.id]) {
+ isSelfToChildStatus = true
+ if (!isSelfToChildDrag) {
+ if (VxeUI.modal) {
+ VxeUI.modal.message({
+ status: 'error',
+ content: getI18n('vxe.error.treeDragChild')
+ })
+ }
+ return
+ }
+ }
+ } else {
+ // 根到根
+ }
+
+ const oldewMatchRest = XEUtils.findTree(collectColumn, item => item.id === oldColumn.id)
+
+ // 改变层级
+ if (isSelfToChildStatus && isSelfToChildDrag) {
+ if (oldewMatchRest) {
+ const { items: oCols, index: oIndex } = oldewMatchRest
+ const childList = oldColumn.children || []
+ childList.forEach(column => {
+ column.parentId = oldColumn.parentId
+ })
+ oCols.splice(oIndex, 1, ...childList)
+ oldColumn.children = []
+ }
+ } else {
+ if (oldewMatchRest) {
+ const { items: oCols, index: oIndex, parent: oParent } = oldewMatchRest
+ oCols.splice(oIndex, 1)
+ if (!oParent) {
+ oafIndex = oIndex
+ }
+ }
+ }
+
+ const newMatchRest = XEUtils.findTree(collectColumn, item => item.id === newColumn.id)
+ if (newMatchRest) {
+ const { items: nCols, index: nIndex, parent: nParent } = newMatchRest
+ // 转子级
+ if (isToChildDrag && prevDragToChild) {
+ oldColumn.parentId = newColumn.id
+ newColumn.children = (newColumn.children || []).concat([oldColumn])
+ } else {
+ oldColumn.parentId = newColumn.parentId
+ nCols.splice(nIndex + dragOffsetIndex, 0, oldColumn)
+ }
+ if (!nParent) {
+ nafIndex = nIndex
+ }
+ }
+
+ XEUtils.eachTree(collectColumn, (column, index, items, path, parent) => {
+ if (!parent) {
+ const sortIndex = index + 1
+ column.renderSortNumber = sortIndex
+ }
+ })
+ } else {
+ oafIndex = XEUtils.findIndexOf(customColumnList, item => item.id === oldColumn.id)
+ customColumnList.splice(oafIndex, 1)
+
+ nafIndex = XEUtils.findIndexOf(customColumnList, item => item.id === newColumn.id)
+ customColumnList.splice(nafIndex + dragOffsetIndex, 0, oldColumn)
+ }
+
+ reactData.isDragColMove = true
+ if (mouseConfig) {
+ if ($xeTable.clearSelected) {
+ $xeTable.clearSelected()
+ }
+ if ($xeTable.clearCellAreas) {
+ $xeTable.clearCellAreas()
+ $xeTable.clearCopyCellArea()
+ }
+ }
+
+ $xeTable.dispatchEvent('column-dragend', {
+ oldColumn,
+ newColumn,
+ dragPos: prevDragPos,
+ offsetIndex: dragOffsetIndex,
+ _index: {
+ newIndex: nafIndex,
+ oldIndex: oafIndex
+ }
+ }, evnt)
+
+ if (immediate) {
+ reactData.customColumnList = collectColumn.slice(0)
+ $xeTable.refreshColumn(true).then(() => {
+ $xeTable.updateCellAreas()
+ $xeTable.handleCustom()
+ $xeTable.saveCustomStore('update:sort')
+ })
+ }
+ }).catch(() => {
+ })
}
- prevDropTrEl.draggable = false
- prevDropTrEl.removeAttribute('drag-pos')
- removeClass(prevDropTrEl, 'active--drag-target')
}
+
+ hideDropTip()
dragColumnRef.value = null
trEl.draggable = false
trEl.removeAttribute('drag-pos')
- if (dragHintEl) {
- dragHintEl.style.display = ''
- }
removeClass(trEl, 'active--drag-target')
removeClass(trEl, 'active--drag-origin')
-
- if (customOpts.immediate) {
- XEUtils.eachTree(customColumnList, (column, index, items, path, parent) => {
- if (!parent) {
- const sortIndex = index + 1
- column.renderSortNumber = sortIndex
- }
- })
- $xeTable.handleCustom()
- $xeTable.saveCustomStore('update:sort')
- }
}
const sortDragoverEvent = (evnt: DragEvent) => {
- const trEl = evnt.currentTarget as HTMLElement
- if (prevDropTrEl !== trEl) {
- removeClass(prevDropTrEl, 'active--drag-target')
- }
- const colid = trEl.getAttribute('colid')
+ const customOpts = computeCustomOpts.value
+ const { immediate } = customOpts
+ const columnDragOpts = computeColumnDragOpts.value
+ const { isCrossDrag, isToChildDrag } = columnDragOpts
+ const optEl = evnt.currentTarget as HTMLElement
+ const hasCtrlKey = evnt.ctrlKey
+ const colid = optEl.getAttribute('colid')
const column = $xeTable.getColumnById(colid)
- // 是否移入有效元行
- if (column && column.level === 1) {
+ const dragCol = dragColumnRef.value
+ // 是否移入有效列
+ if (column && (isCrossDrag || column.level === 1)) {
evnt.preventDefault()
- const offsetY = evnt.clientY - trEl.getBoundingClientRect().y
- const dragOffset = offsetY < trEl.clientHeight / 2 ? 'top' : 'bottom'
- addClass(trEl, 'active--drag-target')
- trEl.setAttribute('drag-pos', dragOffset)
- prevDropTrEl = trEl
+ const offsetY = evnt.clientY - optEl.getBoundingClientRect().y
+ const dragPos = offsetY < optEl.clientHeight / 2 ? 'top' : 'bottom'
+ if ((dragCol && dragCol.id === column.id) || (!isCrossDrag && column.level === 1) || (!immediate && column.level > 1) || column.renderFixed) {
+ showDropTip(evnt, optEl, false, dragPos)
+ return
+ }
+ prevDragToChild = !!(isToChildDrag && hasCtrlKey && immediate)
+ prevDragCol = column
+ prevDragPos = dragPos
+ showDropTip(evnt, optEl, true, dragPos)
}
- updateDropHint(evnt)
}
- const updateDropHint = (evnt: DragEvent) => {
- const dragHintEl = dragHintElemRef.value
- const bodyEl = bodyElemRef.value
- if (!bodyEl) {
- return
- }
- if (dragHintEl) {
- const wrapperEl = bodyEl.parentNode as HTMLElement
- const wrapperRect = wrapperEl.getBoundingClientRect()
- dragHintEl.style.display = 'block'
- dragHintEl.style.top = `${Math.min(wrapperEl.clientHeight - wrapperEl.scrollTop - dragHintEl.clientHeight, evnt.clientY - wrapperRect.y)}px`
- dragHintEl.style.left = `${Math.min(wrapperEl.clientWidth - wrapperEl.scrollLeft - dragHintEl.clientWidth - 16, evnt.clientX - wrapperRect.x)}px`
- }
+ const renderDragTip = () => {
+ const dragCol = dragColumnRef.value
+ return h('div', {}, [
+ h('div', {
+ ref: refDragLineElem,
+ class: 'vxe-table-custom-popup--drag-line'
+ }),
+ h('div', {
+ ref: refDragTipElem,
+ class: 'vxe-table-custom-popup--drag-tip'
+ }, [
+ h('div', {
+ class: 'vxe-table-custom-popup--drag-tip-wrapper'
+ }, [
+ h('div', {
+ class: 'vxe-table-custom-popup--drag-tip-status'
+ }, [
+ h('span', {
+ class: ['vxe-table-custom-popup--drag-tip-normal-status', getIcon().TABLE_DRAG_STATUS_ROW]
+ }),
+ h('span', {
+ class: ['vxe-table-custom-popup--drag-tip-sub-status', getIcon().TABLE_DRAG_STATUS_SUB_ROW]
+ }),
+ h('span', {
+ class: ['vxe-table-custom-popup--drag-tip-disabled-status', getIcon().TABLE_DRAG_DISABLED]
+ })
+ ]),
+ h('div', {
+ class: 'vxe-table--drag-tip-content'
+ }, getI18n('vxe.custom.cstmDragTarget', [dragCol && dragCol.type !== 'html' ? dragCol.getTitle() : '']))
+ ])
+ ])
+ ])
}
const renderSimplePanel = () => {
const { customStore } = props
const { isCustomStatus, customColumnList } = reactData
const customOpts = computeCustomOpts.value
+ const { immediate } = customOpts
+ const columnDragOpts = computeColumnDragOpts.value
const { maxHeight } = customStore
const { checkMethod, visibleMethod, allowVisible, allowSort, allowFixed, trigger, placement } = customOpts
const isMaxFixedColumn = computeIsMaxFixedColumn.value
+ const { isCrossDrag } = columnDragOpts
const slots = customOpts.slots || {}
const headerSlot = slots.header
const topSlot = slots.top
@@ -300,7 +522,6 @@ export default defineComponent({
const customWrapperOns: any = {}
const isAllChecked = customStore.isAll
const isAllIndeterminate = customStore.isIndeterminate
- const dragColumn = dragColumnRef.value
// hover 触发
if (trigger === 'hover') {
customWrapperOns.onMouseenter = handleWrapperMouseenterEvent
@@ -354,38 +575,42 @@ export default defineComponent({
})
])
: createCommentVNode(),
- allowSort && column.level === 1
- ? h('div', {
- class: 'vxe-table-custom--sort-option'
- }, [
- h('span', {
- class: ['vxe-table-custom--sort-btn', {
- 'is--disabled': isDisabled || isHidden
- }],
- title: getI18n('vxe.custom.setting.sortHelpTip'),
- ...(isDisabled || isHidden
- ? {}
- : {
- onMousedown: sortMousedownEvent,
- onMouseup: sortMouseupEvent
- })
+ h('div', {
+ class: 'vxe-table-custom--name-option'
+ }, [
+ allowSort && ((isCrossDrag ? immediate : false) || column.level === 1)
+ ? h('div', {
+ class: 'vxe-table-custom--sort-option'
}, [
- h('i', {
- class: getIcon().TABLE_CUSTOM_SORT
- })
+ h('span', {
+ class: ['vxe-table-custom--sort-btn', {
+ 'is--disabled': isDisabled || isHidden || column.renderFixed
+ }],
+ title: getI18n('vxe.custom.setting.sortHelpTip'),
+ ...(isDisabled || isHidden || column.renderFixed
+ ? {}
+ : {
+ onMousedown: sortMousedownEvent,
+ onMouseup: sortMouseupEvent
+ })
+ }, [
+ h('i', {
+ class: getIcon().TABLE_CUSTOM_SORT
+ })
+ ])
])
- ])
- : createCommentVNode(),
- column.type === 'html'
- ? h('div', {
- key: '1',
- class: 'vxe-table-custom--checkbox-label',
- innerHTML: colTitle
- })
- : h('div', {
- key: '0',
- class: 'vxe-table-custom--checkbox-label'
- }, colTitle),
+ : createCommentVNode(),
+ column.type === 'html'
+ ? h('div', {
+ key: '1',
+ class: 'vxe-table-custom--checkbox-label',
+ innerHTML: colTitle
+ })
+ : h('div', {
+ key: '0',
+ class: 'vxe-table-custom--checkbox-label'
+ }, colTitle)
+ ]),
!parent && allowFixed
? h('div', {
class: 'vxe-table-custom--fixed-option'
@@ -492,10 +717,7 @@ export default defineComponent({
class: 'vxe-table-custom--panel-bottom'
}, $xeTable.callSlot(bottomSlot, params))
: renderEmptyElement($xeTable),
- h('div', {
- ref: dragHintElemRef,
- class: 'vxe-table-custom-popup--drag-hint'
- }, getI18n('vxe.custom.cstmDragTarget', [dragColumn && dragColumn.type !== 'html' ? dragColumn.getTitle() : '']))
+ renderDragTip()
]),
customOpts.showFooter
? h('div', {
@@ -514,7 +736,7 @@ export default defineComponent({
onClick: resetCustomEvent
})
: createCommentVNode(),
- customOpts.immediate
+ immediate
? (VxeUIButtonComponent
? h(VxeUIButtonComponent, {
mode: 'text',
@@ -529,7 +751,7 @@ export default defineComponent({
onClick: cancelCustomEvent
})
: createCommentVNode()),
- customOpts.immediate
+ immediate
? createCommentVNode()
: (VxeUIButtonComponent
? h(VxeUIButtonComponent, {
@@ -551,6 +773,8 @@ export default defineComponent({
const { resizable: allResizable } = tableProps
const { isCustomStatus, customColumnList } = reactData
const customOpts = computeCustomOpts.value
+ const { immediate } = customOpts
+ const columnDragOpts = computeColumnDragOpts.value
const { mode, modalOptions, drawerOptions, allowVisible, allowSort, allowFixed, allowResizable, checkMethod, visibleMethod } = customOpts
const columnOpts = computeColumnOpts.value
const { maxFixedSize } = columnOpts
@@ -559,6 +783,7 @@ export default defineComponent({
const modalOpts = Object.assign({}, modalOptions)
const drawerOpts = Object.assign({}, drawerOptions)
const isMaxFixedColumn = computeIsMaxFixedColumn.value
+ const { isCrossDrag } = columnDragOpts
const slots = customOpts.slots || {}
const headerSlot = slots.header
const topSlot = slots.top
@@ -568,7 +793,6 @@ export default defineComponent({
const trVNs: VNode[] = []
const isAllChecked = customStore.isAll
const isAllIndeterminate = customStore.isIndeterminate
- const dragColumn = dragColumnRef.value
const params = {
$table: $xeTable,
$grid: $xeTable.xegrid,
@@ -639,44 +863,46 @@ export default defineComponent({
])
])
: createCommentVNode(),
- allowSort
- ? h('td', {
- class: 'vxe-table-custom-popup--column-item col--sort'
- }, [
- column.level === 1
- ? h('span', {
- class: ['vxe-table-custom-popup--column-sort-btn', {
- 'is--disabled': isDisabled || isHidden
- }],
- title: getI18n('vxe.custom.setting.sortHelpTip'),
- ...(isDisabled || isHidden
- ? {}
- : {
- onMousedown: sortMousedownEvent,
- onMouseup: sortMouseupEvent
- })
- }, [
- h('i', {
- class: getIcon().TABLE_CUSTOM_SORT
- })
- ])
- : h('span', '-')
- ])
- : createCommentVNode(),
h('td', {
class: 'vxe-table-custom-popup--column-item col--name'
}, [
- column.type === 'html'
- ? h('div', {
- key: '1',
- class: 'vxe-table-custom-popup--name',
- innerHTML: colTitle
- })
- : h('div', {
- key: '0',
- class: 'vxe-table-custom-popup--name',
- title: colTitle
- }, colTitle)
+ h('div', {
+ class: 'vxe-table-custom-popup--name'
+ }, [
+ allowSort
+ ? ((isCrossDrag ? immediate : false) || column.level === 1
+ ? h('div', {
+ class: ['vxe-table-custom-popup--column-sort-btn', {
+ 'is--disabled': isDisabled || isHidden || column.renderFixed
+ }],
+ title: getI18n('vxe.custom.setting.sortHelpTip'),
+ ...(isDisabled || isHidden || column.renderFixed
+ ? {}
+ : {
+ onMousedown: sortMousedownEvent,
+ onMouseup: sortMouseupEvent
+ })
+ }, [
+ h('i', {
+ class: getIcon().TABLE_CUSTOM_SORT
+ })
+ ])
+ : h('div', {
+ class: 'vxe-table-custom-popup--column-sort-placeholder'
+ }))
+ : createCommentVNode(),
+ column.type === 'html'
+ ? h('div', {
+ key: '1',
+ class: 'vxe-table-custom-popup--title',
+ innerHTML: colTitle
+ })
+ : h('div', {
+ key: '0',
+ class: 'vxe-table-custom-popup--title',
+ title: colTitle
+ }, colTitle)
+ ])
]),
allowResizable
? h('td', {
@@ -691,12 +917,17 @@ export default defineComponent({
VxeUINumberInputComponent
? h(VxeUINumberInputComponent, {
type: 'integer',
+ immediate: false,
disabled: isDisabled || isHidden,
modelValue: column.renderResizeWidth,
min: customMinWidth || undefined,
max: customMaxWidth || undefined,
'onUpdate:modelValue' (value: any) {
- column.renderResizeWidth = Math.max(0, Number(value))
+ const width = Math.max(0, Number(value))
+ column.renderResizeWidth = width
+ },
+ onChange () {
+ changeColumnWidth(column)
}
})
: createCommentVNode()
@@ -722,7 +953,7 @@ export default defineComponent({
{ label: getI18n('vxe.custom.setting.fixedRight'), value: 'right', disabled: isDisabled || isHidden || isMaxFixedColumn }
],
'onUpdate:modelValue' (value: any) {
- column.renderFixed = value
+ changeFixedOption(column, value)
}
})
: createCommentVNode()
@@ -757,11 +988,6 @@ export default defineComponent({
class: 'vxe-table-custom-popup--table-col-seq'
})
: createCommentVNode(),
- allowSort
- ? h('col', {
- class: 'vxe-table-custom-popup--table-col-sort'
- })
- : createCommentVNode(),
h('col', {
class: 'vxe-table-custom-popup--table-col-title'
}),
@@ -797,26 +1023,6 @@ export default defineComponent({
])
])
: createCommentVNode(),
- allowSort
- ? h('th', {}, [
- h('span', {
- class: 'vxe-table-custom-popup--table-sort-help-title'
- }, getI18n('vxe.custom.setting.colSort')),
- VxeUITooltipComponent
- ? h(VxeUITooltipComponent, {
- enterable: true,
- content: getI18n('vxe.custom.setting.sortHelpTip'),
- popupClassName: 'vxe-table--ignore-clear'
- }, {
- default: () => {
- return h('i', {
- class: 'vxe-table-custom-popup--table-sort-help-icon vxe-icon-question-circle-fill'
- })
- }
- })
- : createCommentVNode()
- ])
- : createCommentVNode(),
h('th', {}, getI18n('vxe.custom.setting.colTitle')),
allowResizable
? h('th', {}, getI18n('vxe.custom.setting.colResizable'))
@@ -840,10 +1046,7 @@ export default defineComponent({
class: 'vxe-table-custom-popup--table-bottom'
}, $xeTable.callSlot(bottomSlot, params))
: renderEmptyElement($xeTable),
- h('div', {
- ref: dragHintElemRef,
- class: 'vxe-table-custom-popup--drag-hint'
- }, getI18n('vxe.custom.cstmDragTarget', [dragColumn ? dragColumn.getTitle() : '']))
+ renderDragTip()
])
},
footer: () => {
@@ -860,19 +1063,28 @@ export default defineComponent({
onClick: resetCustomEvent
})
: createCommentVNode(),
- VxeUIButtonComponent
- ? h(VxeUIButtonComponent, {
- content: customOpts.resetButtonText || getI18n('vxe.custom.cstmCancel'),
- onClick: cancelCustomEvent
- })
- : createCommentVNode(),
- VxeUIButtonComponent
- ? h(VxeUIButtonComponent, {
- status: 'primary',
- content: customOpts.confirmButtonText || getI18n('vxe.custom.cstmConfirm'),
- onClick: confirmCustomEvent
- })
- : createCommentVNode()
+ immediate
+ ? (VxeUIButtonComponent
+ ? h(VxeUIButtonComponent, {
+ content: customOpts.closeButtonText || getI18n('vxe.table.customClose'),
+ onClick: cancelCloseEvent
+ })
+ : createCommentVNode())
+ : (VxeUIButtonComponent
+ ? h(VxeUIButtonComponent, {
+ content: customOpts.cancelButtonText || getI18n('vxe.table.customCancel'),
+ onClick: cancelCustomEvent
+ })
+ : createCommentVNode()),
+ immediate
+ ? createCommentVNode()
+ : (VxeUIButtonComponent
+ ? h(VxeUIButtonComponent, {
+ status: 'primary',
+ content: customOpts.confirmButtonText || getI18n('vxe.custom.cstmConfirm'),
+ onClick: confirmCustomEvent
+ })
+ : createCommentVNode())
])
}
}
@@ -950,9 +1162,6 @@ export default defineComponent({
if (!VxeUINumberInputComponent) {
errLog('vxe.error.reqComp', ['vxe-number-input'])
}
- if (!VxeUITooltipComponent) {
- errLog('vxe.error.reqComp', ['vxe-tooltip'])
- }
if (!VxeUIRadioGroupComponent) {
errLog('vxe.error.reqComp', ['vxe-radio-group'])
}
diff --git a/packages/table/src/body.ts b/packages/table/src/body.ts
index e6d1a3b1c2..f694551c79 100644
--- a/packages/table/src/body.ts
+++ b/packages/table/src/body.ts
@@ -478,7 +478,7 @@ export default defineComponent({
class: trClass,
rowid: rowid,
style: rowStyle ? (XEUtils.isFunction(rowStyle) ? rowStyle(params) : rowStyle) : null,
- key: rowKey || rowOpts.useKey || rowOpts.drag || treeConfig ? rowid : $rowIndex,
+ key: rowKey || rowOpts.useKey || rowOpts.drag || columnOpts.drag || treeConfig ? rowid : $rowIndex,
...trOn
}, {
default: () => tdVNs
diff --git a/packages/table/src/cell.ts b/packages/table/src/cell.ts
index 2fd694e535..aa73304888 100644
--- a/packages/table/src/cell.ts
+++ b/packages/table/src/cell.ts
@@ -103,10 +103,10 @@ function renderHeaderCellDragIcon (params: VxeTableDefines.CellRenderHeaderParam
const { computeColumnOpts, computeColumnDragOpts } = $table.getComputeMaps()
const columnOpts = computeColumnOpts.value
const columnDragOpts = computeColumnDragOpts.value
- const { showIcon, icon, visibleMethod, disabledMethod } = columnDragOpts
+ const { showIcon, icon, isCrossDrag, visibleMethod, disabledMethod } = columnDragOpts
const isDisabled = disabledMethod && disabledMethod(params)
if (columnOpts.drag && showIcon && (!visibleMethod || visibleMethod(params))) {
- if (!(column.fixed || column.parentId)) {
+ if (!column.fixed && (isCrossDrag || !column.parentId)) {
return h('span', {
key: 'dg',
class: ['vxe-cell--drag-handle', {
diff --git a/packages/table/src/group.ts b/packages/table/src/group.ts
index cb0fef5491..42d731e059 100644
--- a/packages/table/src/group.ts
+++ b/packages/table/src/group.ts
@@ -17,7 +17,7 @@ export default defineComponent({
}
const columnConfig = Cell.createColumn($xeTable, props)
const columnSlots: {
- header?: Slot;
+ header?: Slot
} = {}
if (slots.header) {
diff --git a/packages/table/src/table.ts b/packages/table/src/table.ts
index b3d661a429..29897a4547 100644
--- a/packages/table/src/table.ts
+++ b/packages/table/src/table.ts
@@ -1,6 +1,6 @@
import { defineComponent, h, ComponentPublicInstance, reactive, ref, Ref, provide, inject, nextTick, onActivated, onDeactivated, onBeforeUnmount, onUnmounted, watch, computed, ComputedRef, onMounted } from 'vue'
import XEUtils from 'xe-utils'
-import { browse, isPx, isScale, hasClass, addClass, removeClass, getEventTargetNode, getPaddingTopBottomSize, setScrollTop, setScrollLeft, isNodeElement } from '../../ui/src/dom'
+import { tpImg, browse, isPx, isScale, hasClass, addClass, removeClass, getEventTargetNode, getPaddingTopBottomSize, setScrollTop, setScrollLeft, isNodeElement } from '../../ui/src/dom'
import { getLastZIndex, nextZIndex, hasChildrenList, getFuncText, isEnableConf, formatText, eqEmptyValue } from '../../ui/src/utils'
import { VxeUI } from '../../ui'
import Cell from './cell'
@@ -1115,6 +1115,8 @@ export default defineComponent({
const fullColumnFieldData: Record = internalData.fullColumnFieldData = {}
const mouseOpts = computeMouseOpts.value
const columnOpts = computeColumnOpts.value
+ const columnDragOpts = computeColumnDragOpts.value
+ const { isCrossDrag, isSelfToChildDrag } = columnDragOpts
const rowOpts = computeRowOpts.value
const isGroup = collectColumn.some(hasChildrenList)
let isAllOverflow = !!props.showOverflow
@@ -1128,12 +1130,14 @@ export default defineComponent({
const { id: colid, field, fixed, type, treeNode } = column
const rest = { $index: -1, _index: -1, column, colid, index, items, parent: parent || null, width: 0 }
if (field) {
- if (process.env.VUE_APP_VXE_ENV === 'development') {
- if (fullColumnFieldData[field]) {
- warnLog('vxe.error.colRepet', ['field', field])
- }
+ if (fullColumnFieldData[field]) {
+ errLog('vxe.error.colRepet', ['field', field])
}
fullColumnFieldData[field] = rest
+ } else {
+ if (isCrossDrag || isSelfToChildDrag) {
+ errLog('vxe.error.emptyProp', ['column.field'])
+ }
}
if (!hasFixed && fixed) {
hasFixed = fixed
@@ -1203,10 +1207,10 @@ export default defineComponent({
if (process.env.VUE_APP_VXE_ENV === 'development') {
if (htmlColumn) {
if (!columnOpts.useKey) {
- errLog('vxe.error.reqProp', ['column-config.useKey', 'column.type=html'])
+ errLog('vxe.error.reqProp', ['column-config.useKey & column.type=html'])
}
if (!rowOpts.useKey) {
- errLog('vxe.error.reqProp', ['row-config.useKey', 'column.type=html'])
+ errLog('vxe.error.reqProp', ['row-config.useKey & column.type=html'])
}
}
}
@@ -4099,6 +4103,10 @@ export default defineComponent({
recalculate (reFull?: boolean) {
return new Promise(resolve => {
const { rceTimeout } = internalData
+ const el = refElem.value
+ if (el && el.clientWidth) {
+ autoCellWidth()
+ }
if (rceTimeout) {
clearTimeout(rceTimeout)
nextTick(() => {
@@ -4112,7 +4120,7 @@ export default defineComponent({
internalData.rceTimeout = setTimeout(() => {
internalData.rceTimeout = undefined
handleRecalculateLayout(!!reFull)
- }, 10)
+ }, 20)
})
},
openTooltip (target, content) {
@@ -6007,7 +6015,7 @@ export default defineComponent({
let tipContent = ''
if (tooltipMethod) {
tipContent = `${tooltipMethod({
- column: dragCol
+ column: dragCol as VxeTableDefines.ColumnInfo
}) || ''}`
} else {
tipContent = getI18n('vxe.table.dragTip', [tdEl.textContent || ''])
@@ -6043,11 +6051,18 @@ export default defineComponent({
if (cdLineEl) {
if (showLine) {
const thRect = thEl.getBoundingClientRect()
+ const offsetTop = Math.max(0, thRect.y - wrapperRect.y)
cdLineEl.style.display = 'block'
+ cdLineEl.style.top = `${offsetTop}px`
cdLineEl.style.left = `${Math.max(1, thRect.x - wrapperRect.x)}px`
cdLineEl.style.width = `${thRect.width}px`
- cdLineEl.style.height = `${wrapperRect.height - scrollbarHeight}px`
+ if (prevDragToChild) {
+ cdLineEl.style.height = `${thRect.height}px`
+ } else {
+ cdLineEl.style.height = `${wrapperRect.height - offsetTop - scrollbarHeight}px`
+ }
cdLineEl.setAttribute('drag-pos', dragPos)
+ cdLineEl.setAttribute('drag-to-child', prevDragToChild ? 'y' : 'n')
} else {
cdLineEl.style.display = ''
}
@@ -6260,12 +6275,12 @@ export default defineComponent({
if (!cacheItem) {
cacheItem = { row, rowid, seq, index: -1, _index: -1, $index: -1, items, parent, level, height: 0 }
}
+ cacheItem.row = row
+ cacheItem.items = items
+ cacheItem.parent = parent
+ cacheItem.level = level
+ cacheItem.index = treeConfig && parent ? -1 : index
if (isSource) {
- cacheItem.row = row
- cacheItem.items = items
- cacheItem.parent = parent
- cacheItem.level = level
- cacheItem.index = treeConfig && parent ? -1 : index
fullDataRowIdMaps[rowid] = cacheItem
}
fullAllDataRowIdMaps[rowid] = cacheItem
@@ -7145,8 +7160,9 @@ export default defineComponent({
* 行拖拽
*/
handleRowDragDragstartEvent (evnt) {
- const img = new Image()
if (evnt.dataTransfer) {
+ const img = new Image()
+ img.src = tpImg
evnt.dataTransfer.setDragImage(img, 0, 0)
}
},
@@ -7162,7 +7178,6 @@ export default defineComponent({
const { afterFullData, tableFullData, prevDragRow, prevDragPos } = internalData
const dEndMethod = dragEndMethod || (dragConfig ? dragConfig.dragEndMethod : null)
const dragOffsetIndex = prevDragPos === 'bottom' ? 1 : 0
- console.log(evnt.ctrlKey)
if (prevDragRow && dragRow) {
// 判断是否有拖动
if (prevDragRow !== dragRow) {
@@ -7208,8 +7223,8 @@ export default defineComponent({
return
}
if (oldAllMaps[newRowid]) {
+ isSelfToChildStatus = true
if (!isSelfToChildDrag) {
- isSelfToChildStatus = true
if (VxeUI.modal) {
VxeUI.modal.message({
status: 'error',
@@ -7291,7 +7306,7 @@ export default defineComponent({
reactData.isDragRowMove = true
$xeTable.handleTableData(treeConfig && transform)
- $xeTable.cacheRowMap(true)
+ $xeTable.cacheRowMap()
updateScrollYStatus()
if (!(treeConfig && transform)) {
$xeTable.updateAfterDataIndex()
@@ -7321,6 +7336,7 @@ export default defineComponent({
}
hideDropTip()
clearRowDropOrigin()
+ internalData.prevDragToChild = false
reactData.dragRow = null
reactData.dragCol = null
setTimeout(() => {
@@ -7365,7 +7381,6 @@ export default defineComponent({
}
},
handleCellDragMousedownEvent (evnt, params) {
- evnt.stopPropagation()
const { dragConfig } = props
const rowDragOpts = computeRowDragOpts.value
const { dragStartMethod } = rowDragOpts
@@ -7401,26 +7416,28 @@ export default defineComponent({
* 列拖拽
*/
handleHeaderCellDragDragstartEvent (evnt) {
- const img = new Image()
if (evnt.dataTransfer) {
+ const img = new Image()
+ img.src = tpImg
evnt.dataTransfer.setDragImage(img, 0, 0)
}
},
- handleHeaderCellDragDragendEvent (evnt) {
+ handleColDragSwapEvent (evnt, isSyncColumn, dragCol, prevDragCol, prevDragPos, prevDragToChild) {
const { mouseConfig } = props
const columnDragOpts = computeColumnDragOpts.value
- const { dragEndMethod } = columnDragOpts
- const { dragCol } = reactData
- const { collectColumn, prevDragCol, prevDragPos } = internalData
+ const { isCrossDrag, isSelfToChildDrag, isToChildDrag, dragEndMethod } = columnDragOpts
+ const { collectColumn } = internalData
const dragOffsetIndex = prevDragPos === 'right' ? 1 : 0
if (prevDragCol && dragCol) {
// 判断是否有拖动
if (prevDragCol !== dragCol) {
- Promise.resolve(
+ const oldColumn = dragCol
+ const newColumn = prevDragCol
+ return Promise.resolve(
dragEndMethod
? dragEndMethod({
- oldColumn: dragCol,
- newColumn: prevDragCol,
+ oldColumn,
+ newColumn,
dragPos: prevDragPos as any,
offsetIndex: dragOffsetIndex
})
@@ -7430,6 +7447,101 @@ export default defineComponent({
return
}
+ let oafIndex = -1
+ let nafIndex = -1
+
+ const oldAllMaps: Record = {}
+ XEUtils.eachTree([oldColumn], column => {
+ oldAllMaps[column.id] = column
+ })
+
+ let isSelfToChildStatus = false
+
+ if (oldColumn.parentId && newColumn.parentId) {
+ // 子到子
+
+ if (!isCrossDrag) {
+ return
+ }
+ if (oldAllMaps[newColumn.id]) {
+ isSelfToChildStatus = true
+ if (!isSelfToChildDrag) {
+ if (VxeUI.modal) {
+ VxeUI.modal.message({
+ status: 'error',
+ content: getI18n('vxe.error.treeDragChild')
+ })
+ }
+ return
+ }
+ }
+ } else if (oldColumn.parentId) {
+ // 子到根
+
+ if (!isCrossDrag) {
+ return
+ }
+ } else if (newColumn.parentId) {
+ // 根到子
+
+ if (!isCrossDrag) {
+ return
+ }
+ if (oldAllMaps[newColumn.id]) {
+ isSelfToChildStatus = true
+ if (!isSelfToChildDrag) {
+ if (VxeUI.modal) {
+ VxeUI.modal.message({
+ status: 'error',
+ content: getI18n('vxe.error.treeDragChild')
+ })
+ }
+ return
+ }
+ }
+ } else {
+ // 根到根
+ }
+
+ const oldewMatchRest = XEUtils.findTree(collectColumn, item => item.id === oldColumn.id)
+
+ // 改变层级
+ if (isSelfToChildStatus && isSelfToChildDrag) {
+ if (oldewMatchRest) {
+ const { items: oCols, index: oIndex } = oldewMatchRest
+ const childList = oldColumn.children || []
+ childList.forEach(column => {
+ column.parentId = oldColumn.parentId
+ })
+ oCols.splice(oIndex, 1, ...childList)
+ oldColumn.children = []
+ }
+ } else {
+ if (oldewMatchRest) {
+ const { items: oCols, index: oIndex, parent: oParent } = oldewMatchRest
+ oCols.splice(oIndex, 1)
+ if (!oParent) {
+ oafIndex = oIndex
+ }
+ }
+ }
+
+ const newMatchRest = XEUtils.findTree(collectColumn, item => item.id === newColumn.id)
+ if (newMatchRest) {
+ const { items: nCols, index: nIndex, parent: nParent } = newMatchRest
+ // 转子级
+ if (isToChildDrag && prevDragToChild) {
+ oldColumn.parentId = newColumn.id
+ newColumn.children = (newColumn.children || []).concat([oldColumn])
+ } else {
+ oldColumn.parentId = newColumn.parentId
+ nCols.splice(nIndex + dragOffsetIndex, 0, oldColumn)
+ }
+ if (!nParent) {
+ nafIndex = nIndex
+ }
+ }
+
XEUtils.eachTree(collectColumn, (column, index, items, path, parent) => {
if (!parent) {
const sortIndex = index + 1
@@ -7437,19 +7549,6 @@ export default defineComponent({
}
})
- const oafIndex = XEUtils.findIndexOf(collectColumn, item => item.id === dragCol.id)
- const nafIndex = XEUtils.findIndexOf(collectColumn, item => item.id === prevDragCol.id) + dragOffsetIndex
-
- const newTargetCol = collectColumn[nafIndex]
- if (newTargetCol) {
- // 插入最后位置
- dragCol.renderSortNumber = newTargetCol.renderSortNumber
- newTargetCol.renderSortNumber = dragCol.renderSortNumber + 0.5
- } else {
- // 插入新位置
- dragCol.renderSortNumber = collectColumn.length + 1.5
- }
-
reactData.isDragColMove = true
if (mouseConfig) {
if ($xeTable.clearSelected) {
@@ -7460,15 +7559,10 @@ export default defineComponent({
$xeTable.clearCopyCellArea()
}
}
- tablePrivateMethods.analyColumnWidth()
- nextTick().then(() => {
- $xeTable.updateCellAreas()
- tableMethods.refreshColumn(true)
- })
dispatchEvent('column-dragend', {
- oldColumn: dragCol,
- newColumn: prevDragCol,
+ oldColumn,
+ newColumn,
dragPos: prevDragPos,
offsetIndex: dragOffsetIndex,
_index: {
@@ -7477,13 +7571,25 @@ export default defineComponent({
}
}, evnt)
- $xeTable.saveCustomStore('update:sort')
+ if (isSyncColumn) {
+ return tableMethods.refreshColumn(true).then(() => {
+ $xeTable.updateCellAreas()
+ return $xeTable.saveCustomStore('update:sort')
+ })
+ }
}).catch(() => {
})
}
}
+ return Promise.resolve()
+ },
+ handleHeaderCellDragDragendEvent (evnt) {
+ const { dragCol } = reactData
+ const { prevDragCol, prevDragPos, prevDragToChild } = internalData
+ $xeTable.handleColDragSwapEvent(evnt, true, dragCol, prevDragCol, prevDragPos, prevDragToChild)
hideDropTip()
clearColDropOrigin()
+ internalData.prevDragToChild = false
reactData.dragRow = null
reactData.dragCol = null
setTimeout(() => {
@@ -7492,10 +7598,13 @@ export default defineComponent({
},
handleHeaderCellDragDragoverEvent (evnt) {
const { dragCol } = reactData
+ const columnDragOpts = computeColumnDragOpts.value
+ const { isToChildDrag, isCrossDrag } = columnDragOpts
if (!dragCol) {
evnt.preventDefault()
return
}
+ const hasCtrlKey = evnt.ctrlKey
const thEl = evnt.currentTarget as HTMLElement
const colid = thEl.getAttribute('colid')
const column = $xeTable.getColumnById(colid)
@@ -7504,11 +7613,11 @@ export default defineComponent({
const { dragCol } = reactData
const offsetX = evnt.clientX - thEl.getBoundingClientRect().x
const dragPos = offsetX < thEl.clientWidth / 2 ? 'left' : 'right'
- if (dragCol.id === column.id || column.parentId) {
+ if ((dragCol && dragCol.id === column.id) || (!isCrossDrag && column.parentId)) {
showDropTip(evnt, null, thEl, false, dragPos)
return
}
- internalData.prevDragToChild = false
+ internalData.prevDragToChild = !!(isToChildDrag && hasCtrlKey)
internalData.prevDragCol = column
internalData.prevDragPos = dragPos
showDropTip(evnt, null, thEl, true, dragPos)
@@ -7520,7 +7629,6 @@ export default defineComponent({
}
},
handleHeaderCellDragMousedownEvent (evnt, params) {
- evnt.stopPropagation()
const columnDragOpts = computeColumnDragOpts.value
const { dragStartMethod } = columnDragOpts
const { column } = params
@@ -8376,7 +8484,7 @@ export default defineComponent({
staticColumnFlag.value++
})
watch(staticColumnFlag, () => {
- handleColumn(reactData.staticColumns)
+ handleColumn(XEUtils.clone(reactData.staticColumns))
})
const tableColumnFlag = ref(0)
diff --git a/packages/ui/src/dom.ts b/packages/ui/src/dom.ts
index a7a35340e3..198e0a40f9 100644
--- a/packages/ui/src/dom.ts
+++ b/packages/ui/src/dom.ts
@@ -4,6 +4,8 @@ const reClsMap: { [key: string]: any } = {}
export const browse = XEUtils.browse()
+export const tpImg = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII='
+
export function getPropClass (property: any, params: any) {
return property ? XEUtils.isFunction(property) ? property(params) : property : ''
}
diff --git a/styles/components/table-module/custom.scss b/styles/components/table-module/custom.scss
index 2f19f26d09..317466ab39 100644
--- a/styles/components/table-module/custom.scss
+++ b/styles/components/table-module/custom.scss
@@ -41,7 +41,7 @@
position: absolute;
left: -1px;
width: calc(100% + 1px);
- height: 3px;
+ height: 2px;
background-color: var(--vxe-ui-font-primary-color);
z-index: 12;
}
@@ -95,6 +95,7 @@
}
.vxe-table-custom--body {
+ position: relative;
display: block;
flex-grow: 1;
overflow-x: hidden;
@@ -107,15 +108,12 @@
padding: 0;
& > li {
max-width: 26em;
- min-width: 17em;
+ min-width: 18em;
padding: 0.2em 1em 0.2em 1em;
@for $i from 2 through 8 {
- $interval: $i - 1 + 0.2;
+ $interval: $i - 1 + 0.5;
&.level--#{$i}{
- padding-left: #{$interval + 2.3}em;
- .vxe-checkbox--icon {
- left: #{$interval + 0.6}em;
- }
+ padding-left: #{$interval + 1.2}em;
}
}
}
@@ -130,7 +128,6 @@
}
.vxe-table-custom--panel-list {
- padding: 0.2em 0;
.vxe-table-custom--checkbox-option {
&:hover {
background-color: var(--vxe-ui-table-row-hover-background-color);
@@ -182,6 +179,12 @@
cursor: not-allowed;
}
}
+.vxe-table-custom--name-option {
+ flex-grow: 1;
+ display: flex;
+ flex-direction: row;
+ overflow: hidden;
+}
.vxe-table-custom--checkbox-label {
flex-grow: 1;
overflow: hidden;
@@ -199,6 +202,7 @@
}
.vxe-table-custom-popup--body {
+ position: relative;
overflow: auto;
height: 100%;
outline: 0;
@@ -248,13 +252,43 @@
}
}
-.vxe-table-custom-popup--drag-hint {
+/*拖拽列*/
+.vxe-table-custom-popup--drag-line {
+ display: none;
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: 11;
+ pointer-events: none;
+}
+.vxe-table-custom-popup--drag-line {
+ width: 100%;
+ height: 1px;
+ border: 2px solid transparent;
+ &[drag-pos="top"] {
+ border-top-color: var(--vxe-ui-font-primary-color);
+ }
+ &[drag-pos="bottom"] {
+ border-bottom-color: var(--vxe-ui-font-primary-color);
+ }
+ &[drag-to-child="y"] {
+ border-top-color: transparent;
+ border-bottom-color: transparent;
+ border-left-color: var(--vxe-ui-status-success-color);
+ }
+ &.is--guides {
+ background-color: var( --vxe-ui-table-drag-over-background-color);
+ }
+}
+
+.vxe-table-custom-popup--drag-tip {
display: none;
position: absolute;
top: 0;
left: 0;
- padding: 0.6em 1em 0.6em 1.6em;
- max-width: 300px;
+ padding: 0.6em 1.4em;
+ max-width: 50%;
+ min-width: 100px;
border-radius: var(--vxe-ui-border-radius);
overflow: hidden;
text-overflow: ellipsis;
@@ -264,9 +298,53 @@
background-color: var(--vxe-ui-layout-background-color);
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.2);
z-index: 33;
+ &[drag-status="normal"] {
+ .vxe-table-custom-popup--drag-tip-normal-status {
+ display: block;
+ }
+ }
+ &[drag-status="sub"] {
+ .vxe-table-custom-popup--drag-tip-sub-status {
+ display: block;
+ }
+ }
+ &[drag-status="disabled"] {
+ .vxe-table-custom-popup--drag-tip-disabled-status {
+ display: block;
+ }
+ }
+}
+.vxe-table-custom-popup--drag-tip-wrapper {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+}
+.vxe-table-custom-popup--drag-tip-status {
+ padding-right: 0.4em;
+}
+.vxe-table-custom-popup--drag-tip-disabled-status {
+ display: none;
+ flex-shrink: 0;
+ color: var(--vxe-ui-status-error-color)
+}
+.vxe-table-custom-popup--drag-tip-normal-status,
+.vxe-table-custom-popup--drag-tip-sub-status {
+ display: none;
+}
+.vxe-table-custom-popup--drag-tip-content {
+ flex-grow: 1;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
}
.vxe-table-custom-popup--name {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+}
+.vxe-table-custom-popup--title {
+ flex-grow: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
@@ -285,7 +363,6 @@
.vxe-table-custom-popup--column-item {
position: relative;
- &.col--sort,
&.col--visible,
&.col--resizable,
&.col--fixed {
@@ -365,6 +442,9 @@
transition: transform 0.35s;
}
+.vxe-table-custom-popup--column-sort-placeholder {
+ padding: 0.2em 0.5em;
+}
.vxe-table-custom-popup--column-sort-btn {
font-size: 1.2em;
padding: 0.2em 0.5em;
diff --git a/styles/components/table.scss b/styles/components/table.scss
index 363bc4c25c..25baaadaff 100644
--- a/styles/components/table.scss
+++ b/styles/components/table.scss
@@ -1286,6 +1286,11 @@
&[drag-pos="right"] {
border-right-color: var(--vxe-ui-font-primary-color);
}
+ &[drag-to-child="y"] {
+ border-left-color: transparent;
+ border-right-color: transparent;
+ border-bottom-color: var(--vxe-ui-status-success-color);
+ }
&.is--guides {
background-color: var( --vxe-ui-table-drag-over-background-color);
}