mirror of
https://gitee.com/xuliangzhan_admin/vxe-table.git
synced 2026-01-21 05:27:57 +08:00
修复树结构按键操作无法回退到上一级问题
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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')
|
||||
}
|
||||
|
||||
@@ -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>`
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
},
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
4
types/table.d.ts
vendored
@@ -1558,6 +1558,10 @@ export interface TableKeyboardConfig {
|
||||
* 是否开启删除键功能
|
||||
*/
|
||||
isDel?: boolean;
|
||||
/**
|
||||
* 是否开启回退键功能
|
||||
*/
|
||||
isBack?: boolean
|
||||
/**
|
||||
* 是否开启回车移动上下行移动
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user