修复树结构按键操作无法回退到上一级问题

This commit is contained in:
xuliangzhan
2024-06-22 20:41:54 +08:00
parent b740764640
commit 58992fdbe5
9 changed files with 114 additions and 81 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "vxe-table",
"version": "3.8.8-beta.6",
"version": "3.8.8-beta.8",
"description": "一个基于 vue 的 PC 端表单/表格组件支持增删改查、虚拟树、列拖拽懒加载、快捷菜单、数据校验、树形结构、打印导出、自定义模板、渲染器、JSON 配置式...",
"scripts": {
"update": "npm install --legacy-peer-deps",

View File

@@ -425,7 +425,7 @@ export default {
const { actived, focused } = editStore
const { row, column } = params
const { editRender } = column
const cell = params.cell = (params.cell || this.getCell(row, column))
const cell = params.cell = (params.cell || this.getCellElement(row, column))
const beforeEditMethod = editOpts.beforeEditMethod || editOpts.activeMethod
if (cell && isEnableConf(editConfig) && isEnableConf(editRender)) {
// 激活编辑
@@ -678,7 +678,7 @@ export default {
const column = XEUtils.isString(fieldOrColumn) ? this.getColumnByField(fieldOrColumn) : fieldOrColumn
if (row && column && isEnableConf(editConfig) && isEnableConf(column.editRender)) {
return this.scrollToRow(row, true).then(() => {
const cell = this.getCell(row, column)
const cell = this.getCellElement(row, column)
if (cell) {
this.handleActived({ row, rowIndex: this.getRowIndex(row), column, columnIndex: this.getColumnIndex(column), cell, $table: this })
this.lastCallTime = Date.now()
@@ -696,7 +696,7 @@ export default {
if (row && column && editOpts.trigger !== 'manual') {
const rowIndex = this.findRowIndexOf(tableData, row)
if (rowIndex > -1) {
const cell = this.getCell(row, column)
const cell = this.getCellElement(row, column)
const params = { row, rowIndex, column, columnIndex: visibleColumn.indexOf(column), cell }
this.handleSelected(params, {})
}
@@ -772,7 +772,7 @@ export default {
const { row, column } = selected
this.reColSdCls()
if (row && column) {
const cell = this.getCell(row, column)
const cell = this.getCellElement(row, column)
if (cell) {
DomTools.addClass(cell, 'col--selected')
}

View File

@@ -137,7 +137,7 @@ function getLabelData ($xetable, opts, columns, datas) {
htmlCellElem.innerHTML = cellValue
cellValue = htmlCellElem.innerText.trim()
} else {
const cell = $xetable.getCell(row, column)
const cell = $xetable.getCellElement(row, column)
if (cell) {
cellValue = cell.innerText.trim()
}
@@ -193,7 +193,7 @@ function getLabelData ($xetable, opts, columns, datas) {
htmlCellElem.innerHTML = cellValue
cellValue = htmlCellElem.innerText.trim()
} else {
const cell = $xetable.getCell(row, column)
const cell = $xetable.getCellElement(row, column)
if (cell) {
cellValue = cell.innerText.trim()
}
@@ -226,7 +226,7 @@ function getHeaderTitle ($xetable, opts, column) {
return headExportMethod ? headExportMethod({ column, options: opts, $table: $xetable }) : ((opts.original ? column.property : column.getTitle()) || '')
}
function getFooterCellValue ($xetable, opts, items, column) {
function getFooterCellValue ($xetable, opts, row, column) {
const { columnOpts } = $xetable
const renderOpts = column.editRender || column.cellRender
let footLabelMethod = column.footerExportMethod
@@ -240,8 +240,14 @@ function getFooterCellValue ($xetable, opts, items, column) {
footLabelMethod = columnOpts.footerExportMethod
}
const _columnIndex = $xetable.getVTColumnIndex(column)
const cellValue = footLabelMethod ? footLabelMethod({ $table: $xetable, items, itemIndex: _columnIndex, row: items, _columnIndex, column, options: opts }) : XEUtils.toValueString(items[_columnIndex])
return cellValue
if (footLabelMethod) {
return footLabelMethod({ $table: $xetable, items: row, itemIndex: _columnIndex, row, _columnIndex, column, options: opts })
}
// 兼容老模式
if (XEUtils.isArray(row)) {
return XEUtils.toValueString(row[_columnIndex])
}
return XEUtils.get(row, column.field)
}
function getFooterData (opts, footerTableData) {
@@ -290,8 +296,8 @@ function toCsv ($xetable, opts, columns, datas) {
if (opts.isFooter) {
const footerTableData = $xetable.footerTableData
const footers = getFooterData(opts, footerTableData)
footers.forEach(rows => {
content += columns.map(column => toTxtCellLabel(getFooterCellValue($xetable, opts, rows, column))).join(',') + enterSymbol
footers.forEach(row => {
content += columns.map(column => toTxtCellLabel(getFooterCellValue($xetable, opts, row, column))).join(',') + enterSymbol
})
}
return content
@@ -308,8 +314,8 @@ function toTxt ($xetable, opts, columns, datas) {
if (opts.isFooter) {
const footerTableData = $xetable.footerTableData
const footers = getFooterData(opts, footerTableData)
footers.forEach(rows => {
content += columns.map(column => toTxtCellLabel(getFooterCellValue($xetable, opts, rows, column))).join(',') + enterSymbol
footers.forEach(row => {
content += columns.map(column => toTxtCellLabel(getFooterCellValue($xetable, opts, row, column))).join(',') + enterSymbol
})
}
return content
@@ -485,12 +491,12 @@ function toHtml ($xetable, opts, columns, datas) {
const footers = getFooterData(opts, footerTableData)
if (footers.length) {
tables.push('<tfoot>')
footers.forEach(rows => {
footers.forEach(row => {
tables.push(
`<tr>${columns.map(column => {
const footAlign = column.footerAlign || column.align || allFooterAlign || allAlign
const classNames = hasEllipsis($xetable, column, 'showOverflow', allColumnOverflow) ? ['col--ellipsis'] : []
const cellValue = getFooterCellValue($xetable, opts, rows, column)
const cellValue = getFooterCellValue($xetable, opts, row, column)
if (footAlign) {
classNames.push(`col--${footAlign}`)
}
@@ -536,8 +542,8 @@ function toXML ($xetable, opts, columns, datas) {
if (opts.isFooter) {
const footerTableData = $xetable.footerTableData
const footers = getFooterData(opts, footerTableData)
footers.forEach(rows => {
xml += `<Row>${columns.map(column => `<Cell><Data ss:Type="String">${getFooterCellValue($xetable, opts, rows, column)}</Data></Cell>`).join('')}</Row>`
footers.forEach(row => {
xml += `<Row>${columns.map(column => `<Cell><Data ss:Type="String">${getFooterCellValue($xetable, opts, row, column)}</Data></Cell>`).join('')}</Row>`
})
}
return `${xml}</Table></Worksheet></Workbook>`

View File

@@ -93,7 +93,7 @@ export default {
}
params.columnIndex = targetColumnIndex
params.column = targetColumn
params.cell = this.getCell(params.row, params.column)
params.cell = this.getCellElement(params.row, params.column)
if (editConfig) {
if (editOpts.trigger === 'click' || editOpts.trigger === 'dblclick') {
if (editOpts.mode === 'row') {
@@ -165,7 +165,7 @@ export default {
params.column = visibleColumn[params.columnIndex]
}
this.scrollToRow(params.row, params.column).then(() => {
params.cell = this.getCell(params.row, params.column)
params.cell = this.getCellElement(params.row, params.column)
this.handleSelected(params, evnt)
})
},

View File

@@ -180,7 +180,7 @@ export default {
const { keyboard, row, column } = params
if (keyboard && row && column) {
this.scrollToRow(row, column).then(() => {
const cell = this.getCell(row, column)
const cell = this.getCellElement(row, column)
const { boundingTop, boundingLeft } = DomTools.getAbsolutePos(cell)
top = boundingTop + scrollTop + Math.floor(cell.offsetHeight / 2)
left = boundingLeft + scrollLeft + Math.floor(cell.offsetWidth / 2)

View File

@@ -254,7 +254,6 @@ export const Cell = {
}
if (!trigger || trigger === 'default') {
on.click = evnt => {
evnt.stopPropagation()
$table.triggerTreeExpandEvent(evnt, params)
}
}
@@ -337,7 +336,6 @@ export const Cell = {
on = {
click (evnt) {
if (!isDisabled && isVisible) {
evnt.stopPropagation()
$table.triggerRadioRowEvent(evnt, params)
}
}
@@ -395,7 +393,6 @@ export const Cell = {
on = {
click (evnt) {
if (!isAllCheckboxDisabled) {
evnt.stopPropagation()
$table.triggerCheckAllEvent(evnt, !isAllCheckboxSelected)
}
}
@@ -452,7 +449,6 @@ export const Cell = {
on = {
click (evnt) {
if (!isDisabled && isVisible) {
evnt.stopPropagation()
$table.triggerCheckRowEvent(evnt, params, !isChecked)
}
}
@@ -517,7 +513,6 @@ export const Cell = {
on = {
click (evnt) {
if (!isDisabled && isVisible) {
evnt.stopPropagation()
$table.triggerCheckRowEvent(evnt, params, !isChecked)
}
}
@@ -592,7 +587,6 @@ export const Cell = {
}],
on: {
click (evnt) {
evnt.stopPropagation()
$table.triggerRowExpandEvent(evnt, params)
}
}

View File

@@ -1103,6 +1103,63 @@ const Methods = {
}
return this.$nextTick()
},
getCellElement (row, fieldOrColumn) {
const column = handleFieldOrColumn(this, fieldOrColumn)
if (!column) {
return null
}
const { $refs } = this
const rowid = getRowid(this, row)
let bodyElem = null
if (column) {
bodyElem = $refs[`${column.fixed || 'table'}Body`] || $refs.tableBody
}
if (bodyElem && bodyElem.$el) {
return bodyElem.$el.querySelector(`.vxe-body--row[rowid="${rowid}"] .${column.id}`)
}
return null
},
getCellLabel (row, fieldOrColumn) {
const column = handleFieldOrColumn(this, fieldOrColumn)
if (!column) {
return null
}
const formatter = column.formatter
const cellValue = UtilTools.getCellValue(row, column)
let cellLabel = cellValue
if (formatter) {
let rest, formatData
const { fullAllDataRowMap } = this
const colid = column.id
const cacheFormat = fullAllDataRowMap.has(row)
if (cacheFormat) {
rest = fullAllDataRowMap.get(row)
formatData = rest.formatData
if (!formatData) {
formatData = fullAllDataRowMap.get(row).formatData = {}
}
if (rest && formatData[colid]) {
if (formatData[colid].value === cellValue) {
return formatData[colid].label
}
}
}
const formatParams = { cellValue, row, rowIndex: this.getRowIndex(row), column, columnIndex: this.getColumnIndex(column) }
if (XEUtils.isString(formatter)) {
const gFormatOpts = formats.get(formatter)
cellLabel = gFormatOpts && gFormatOpts.cellFormatMethod ? gFormatOpts.cellFormatMethod(formatParams) : ''
} else if (XEUtils.isArray(formatter)) {
const gFormatOpts = formats.get(formatter[0])
cellLabel = gFormatOpts && gFormatOpts.cellFormatMethod ? gFormatOpts.cellFormatMethod(formatParams, ...formatter.slice(1)) : ''
} else {
cellLabel = formatter(formatParams)
}
if (formatData) {
formatData[colid] = { value: cellValue, label: cellLabel }
}
}
return cellLabel
},
/**
* 检查是否为临时行数据
* @param {Row} row 行对象
@@ -1156,6 +1213,13 @@ const Methods = {
const columns = this.visibleColumn
return XEUtils.isUndefined(columnIndex) ? columns.slice(0) : columns[columnIndex]
},
/**
* 根据列获取列的唯一主键
*/
getColid (fieldOrColumn) {
const column = handleFieldOrColumn(this, fieldOrColumn)
return column ? column.id : null
},
/**
* 根据列的唯一主键获取列
* @param {String} colid 列主键
@@ -2734,7 +2798,7 @@ const Methods = {
const { filterStore, isCtxMenu, ctxMenuStore, editStore, editOpts, editConfig, mouseConfig, mouseOpts, keyboardConfig, keyboardOpts, treeConfig, treeOpts, highlightCurrentRow, currentRow, bodyCtxMenu, rowOpts } = this
const { selected, actived } = editStore
const { keyCode } = evnt
const isBack = keyCode === 8
const hasBackspaceKey = keyCode === 8
const isTab = keyCode === 9
const isEnter = keyCode === 13
const isEsc = keyCode === 27
@@ -2854,11 +2918,11 @@ const Methods = {
} else if (actived.row || actived.column) {
this.moveTabSelected(actived.args, hasShiftKey, evnt)
}
} else if (keyboardConfig && (isDel || (treeConfig && (rowOpts.isCurrent || highlightCurrentRow) && currentRow ? isBack && keyboardOpts.isArrow : isBack))) {
} else if (keyboardConfig && (treeConfig || isEnableConf(editConfig)) && (isDel || (treeConfig && (rowOpts.isCurrent || highlightCurrentRow) && currentRow ? hasBackspaceKey && keyboardOpts.isArrow : hasBackspaceKey))) {
if (!isEditStatus) {
const { delMethod, backMethod } = keyboardOpts
// 如果是删除键
if (keyboardOpts.isDel && (selected.row || selected.column)) {
if (keyboardOpts.isDel && isEnableConf(editConfig) && (selected.row || selected.column)) {
const delPaqrams = {
row: selected.row,
rowIndex: this.getRowIndex(selected.row),
@@ -2871,7 +2935,7 @@ const Methods = {
} else {
setCellValue(selected.row, selected.column, null)
}
if (isBack) {
if (hasBackspaceKey) {
if (backMethod) {
backMethod({
row: selected.row,
@@ -2888,7 +2952,7 @@ const Methods = {
this.updateFooter()
}
this.emitEvent('cell-delete-value', delPaqrams, evnt)
} else if (isBack && keyboardOpts.isArrow && treeConfig && (rowOpts.isCurrent || highlightCurrentRow) && currentRow) {
} else if (hasBackspaceKey && keyboardOpts.isArrow && treeConfig && (rowOpts.isCurrent || highlightCurrentRow) && currentRow) {
// 如果树形表格回退键关闭当前行返回父节点
const { parent: parentRow } = XEUtils.findTree(this.afterFullData, item => item === currentRow, { children: childrenField })
if (parentRow) {
@@ -3423,6 +3487,7 @@ const Methods = {
if (trigger === 'manual') {
return
}
evnt.stopPropagation()
if (checkboxOpts.isShiftKey && evnt.shiftKey && !this.treeConfig) {
const checkboxRecords = this.getCheckboxRecords()
if (checkboxRecords.length) {
@@ -3797,6 +3862,9 @@ const Methods = {
if (trigger === 'manual') {
return
}
if (evnt) {
evnt.stopPropagation()
}
this.handleCheckAllEvent(evnt, value)
},
/**
@@ -3863,6 +3931,7 @@ const Methods = {
if (trigger === 'manual') {
return
}
evnt.stopPropagation()
let newValue = row
let isChange = oldValue !== newValue
if (isChange) {
@@ -4442,6 +4511,7 @@ const Methods = {
if (trigger === 'manual') {
return
}
evnt.stopPropagation()
const rowid = getRowid(this, row)
if (!lazy || !rowExpandLazyLoadedMaps[rowid]) {
const expanded = !this.isRowExpandByRow(row)
@@ -4720,6 +4790,7 @@ const Methods = {
if (trigger === 'manual') {
return
}
evnt.stopPropagation()
const rowid = getRowid(this, row)
if (!lazy || !treeExpandLazyLoadedMaps[rowid]) {
const expanded = !this.isTreeExpandByRow(row)
@@ -5290,7 +5361,7 @@ const Methods = {
const type = 'change'
if (this.hasCellRules) {
if (this.hasCellRules(type, row, column)) {
const cell = this.getCell(row, column)
const cell = this.getCellElement(row, column)
if (cell) {
return this.validCellRules(type, row, column, cellValue)
.then(() => {
@@ -5435,54 +5506,12 @@ const Methods = {
/*************************
* Publish methods
*************************/
/**
* 已废弃,被 getCellElement 替换
* @deprecated
*/
getCell (row, column) {
const { $refs } = this
const rowid = getRowid(this, row)
let bodyElem = null
if (column) {
bodyElem = $refs[`${column.fixed || 'table'}Body`] || $refs.tableBody
}
if (bodyElem && bodyElem.$el) {
return bodyElem.$el.querySelector(`.vxe-body--row[rowid="${rowid}"] .${column.id}`)
}
return null
},
getCellLabel (row, column) {
const formatter = column.formatter
const cellValue = UtilTools.getCellValue(row, column)
let cellLabel = cellValue
if (formatter) {
let rest, formatData
const { fullAllDataRowMap } = this
const colid = column.id
const cacheFormat = fullAllDataRowMap.has(row)
if (cacheFormat) {
rest = fullAllDataRowMap.get(row)
formatData = rest.formatData
if (!formatData) {
formatData = fullAllDataRowMap.get(row).formatData = {}
}
if (rest && formatData[colid]) {
if (formatData[colid].value === cellValue) {
return formatData[colid].label
}
}
}
const formatParams = { cellValue, row, rowIndex: this.getRowIndex(row), column, columnIndex: this.getColumnIndex(column) }
if (XEUtils.isString(formatter)) {
const gFormatOpts = formats.get(formatter)
cellLabel = gFormatOpts && gFormatOpts.cellFormatMethod ? gFormatOpts.cellFormatMethod(formatParams) : ''
} else if (XEUtils.isArray(formatter)) {
const gFormatOpts = formats.get(formatter[0])
cellLabel = gFormatOpts && gFormatOpts.cellFormatMethod ? gFormatOpts.cellFormatMethod(formatParams, ...formatter.slice(1)) : ''
} else {
cellLabel = formatter(formatParams)
}
if (formatData) {
formatData[colid] = { value: cellValue, label: cellLabel }
}
}
return cellLabel
return this.getCellElement(row, column)
},
findRowIndexOf (list, row) {
return row ? XEUtils.findIndexOf(list, item => this.eqRow(item, row)) : -1

View File

@@ -221,7 +221,7 @@ export default {
})
}
const posAndFinish = () => {
firstErrParams.cell = this.getCell(firstErrParams.row, firstErrParams.column)
firstErrParams.cell = this.getCellElement(firstErrParams.row, firstErrParams.column)
DomTools.scrollToView(firstErrParams.cell)
this.handleValidError(firstErrParams).then(finish)
}

4
types/table.d.ts vendored
View File

@@ -1558,6 +1558,10 @@ export interface TableKeyboardConfig {
* 是否开启删除键功能
*/
isDel?: boolean;
/**
* 是否开启回退键功能
*/
isBack?: boolean
/**
* 是否开启回车移动上下行移动
*/