diff --git a/package.json b/package.json index 696ca509d..46cb7725b 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/packages/edit/src/mixin.js b/packages/edit/src/mixin.js index 002c4ba8b..99a4d3439 100644 --- a/packages/edit/src/mixin.js +++ b/packages/edit/src/mixin.js @@ -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') } diff --git a/packages/export/src/mixin.js b/packages/export/src/mixin.js index 5ca4acb74..444b38ab7 100644 --- a/packages/export/src/mixin.js +++ b/packages/export/src/mixin.js @@ -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('') - footers.forEach(rows => { + footers.forEach(row => { tables.push( `${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 += `${columns.map(column => `${getFooterCellValue($xetable, opts, rows, column)}`).join('')}` + footers.forEach(row => { + xml += `${columns.map(column => `${getFooterCellValue($xetable, opts, row, column)}`).join('')}` }) } return `${xml}` diff --git a/packages/keyboard/src/mixin.js b/packages/keyboard/src/mixin.js index fa86cbf79..f37649b77 100644 --- a/packages/keyboard/src/mixin.js +++ b/packages/keyboard/src/mixin.js @@ -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) }) }, diff --git a/packages/menu/src/mixin.js b/packages/menu/src/mixin.js index b0f84535b..d64cfa3b9 100644 --- a/packages/menu/src/mixin.js +++ b/packages/menu/src/mixin.js @@ -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) diff --git a/packages/table/src/cell.js b/packages/table/src/cell.js index 464124dd0..2285c2f01 100644 --- a/packages/table/src/cell.js +++ b/packages/table/src/cell.js @@ -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) } } diff --git a/packages/table/src/methods.js b/packages/table/src/methods.js index 79428a4ce..029511037 100644 --- a/packages/table/src/methods.js +++ b/packages/table/src/methods.js @@ -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 diff --git a/packages/validator/src/mixin.js b/packages/validator/src/mixin.js index 82eee99d5..57189ff64 100644 --- a/packages/validator/src/mixin.js +++ b/packages/validator/src/mixin.js @@ -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) } diff --git a/types/table.d.ts b/types/table.d.ts index 79e9a394f..1ce5288ba 100644 --- a/types/table.d.ts +++ b/types/table.d.ts @@ -1558,6 +1558,10 @@ export interface TableKeyboardConfig { * 是否开启删除键功能 */ isDel?: boolean; + /** + * 是否开启回退键功能 + */ + isBack?: boolean /** * 是否开启回车移动上下行移动 */