import { h, VNode } from 'vue' import XEUtils from 'xe-utils' import { VxeUI } from '@vxe-ui/core' import { getFuncText, isEnableConf, formatText, eqEmptyValue } from '../../ui/src/utils' import { updateCellTitle } from '../../ui/src/dom' import { createColumn, getRowid } from './util' import { getSlotVNs } from '../../ui/src/vn' import type { VxeTableConstructor, VxeTableDefines, VxeTablePrivateMethods, VxeComponentSlotType } from '../../../types' const { getConfig, getI18n, getIcon, renderer, renderEmptyElement } = VxeUI function renderTitlePrefixIcon(params: VxeTableDefines.CellRenderHeaderParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }) { const { $table, column } = params const titlePrefix = column.titlePrefix || column.titleHelp if (titlePrefix) { return h( 'span', { class: ['vxe-cell-title-prefix-icon', titlePrefix.iconStatus ? `theme--${titlePrefix.iconStatus}` : ''], onMouseenter(evnt: MouseEvent) { $table.triggerHeaderTitleEvent(evnt, titlePrefix, params) }, onMouseleave(evnt: MouseEvent) { $table.handleTargetLeaveEvent(evnt) } }, [ h('i', { class: titlePrefix.icon || getIcon().TABLE_TITLE_PREFIX }) ] ) } return renderEmptyElement($table) } function renderTitleSuffixIcon(params: VxeTableDefines.CellRenderHeaderParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }) { const { $table, column } = params const titleSuffix = column.titleSuffix if (titleSuffix) { return h( 'span', { class: ['vxe-cell-title-suffix-icon', titleSuffix.iconStatus ? `theme--${titleSuffix.iconStatus}` : ''], onMouseenter(evnt: MouseEvent) { $table.triggerHeaderTitleEvent(evnt, titleSuffix, params) }, onMouseleave(evnt: MouseEvent) { $table.handleTargetLeaveEvent(evnt) } }, [ h('i', { class: titleSuffix.icon || getIcon().TABLE_TITLE_SUFFIX }) ] ) } return renderEmptyElement($table) } function renderCellDragIcon(params: VxeTableDefines.CellRenderBodyParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }) { const { $table, column } = params const { context } = $table const tableSlots = context.slots const tableProps = $table.props const { slots } = column const { dragConfig } = tableProps const { computeRowDragOpts } = $table.getComputeMaps() const rowDragOpts = computeRowDragOpts.value const { icon, trigger, disabledMethod } = rowDragOpts const rDisabledMethod = disabledMethod || (dragConfig ? dragConfig.rowDisabledMethod : null) const isDisabled = rDisabledMethod && rDisabledMethod(params) const rowDragIconSlot = (slots ? slots.rowDragIcon || slots['row-drag-icon'] : null) || tableSlots.rowDragIcon || tableSlots['row-drag-icon'] const ons: Record = {} if (trigger !== 'cell') { ons.onMousedown = (evnt: MouseEvent) => { if (!isDisabled) { $table.handleCellDragMousedownEvent(evnt, params) } } ons.onMouseup = $table.handleCellDragMouseupEvent } return h( 'span', { key: 'dg', class: [ 'vxe-cell--drag-handle', { 'is--disabled': isDisabled } ], ...ons }, rowDragIconSlot ? $table.callSlot(rowDragIconSlot, params) : [ h('i', { class: icon || (dragConfig ? dragConfig.rowIcon : '') || getIcon().TABLE_DRAG_ROW }) ] ) } function renderCellBaseVNs(params: VxeTableDefines.CellRenderBodyParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }, content: VxeComponentSlotType | VxeComponentSlotType[]) { const { $table, column, level } = params const { dragSort } = column const tableProps = $table.props const { treeConfig, dragConfig } = tableProps const { computeRowOpts, computeRowDragOpts, computeTreeOpts } = $table.getComputeMaps() const rowOpts = computeRowOpts.value const rowDragOpts = computeRowDragOpts.value const treeOpts = computeTreeOpts.value const { showIcon, isPeerDrag, isCrossDrag, visibleMethod } = rowDragOpts const rVisibleMethod = visibleMethod || (dragConfig ? dragConfig.rowVisibleMethod : null) const vns: VxeComponentSlotType[] = [] if (dragSort && rowOpts.drag && (showIcon || (dragConfig ? dragConfig.showRowIcon : false)) && (!rVisibleMethod || rVisibleMethod(params))) { if (treeConfig) { if (treeOpts.transform && (isPeerDrag || isCrossDrag || !level)) { vns.push(renderCellDragIcon(params)) } } else { vns.push(renderCellDragIcon(params)) } } return vns.concat(XEUtils.isArray(content) ? content : [content]) } function renderHeaderCellDragIcon(params: VxeTableDefines.CellRenderHeaderParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }) { const { $table, column } = params const { context } = $table const tableSlots = context.slots const { slots } = column const { computeColumnOpts, computeColumnDragOpts } = $table.getComputeMaps() const columnOpts = computeColumnOpts.value const columnDragOpts = computeColumnDragOpts.value const { showIcon, icon, trigger, isPeerDrag, isCrossDrag, visibleMethod, disabledMethod } = columnDragOpts if (columnOpts.drag && showIcon && (!visibleMethod || visibleMethod(params))) { if (!column.fixed && (isPeerDrag || isCrossDrag || !column.parentId)) { const isDisabled = disabledMethod && disabledMethod(params) const columnDragIconSlot = (slots ? slots.columnDragIcon || slots['column-drag-icon'] : null) || tableSlots.columnDragIcon || tableSlots['column-drag-icon'] const ons: Record = {} if (trigger !== 'cell') { ons.onMousedown = (evnt: MouseEvent) => { if (!isDisabled) { $table.handleHeaderCellDragMousedownEvent(evnt, params) } } ons.onMouseup = $table.handleHeaderCellDragMouseupEvent } return h( 'span', { key: 'dg', class: [ 'vxe-cell--drag-handle', { 'is--disabled': isDisabled } ], ...ons }, columnDragIconSlot ? $table.callSlot(columnDragIconSlot, params) : [ h('i', { class: icon || getIcon().TABLE_DRAG_COLUMN }) ] ) } } return renderEmptyElement($table) } function renderHeaderCellBaseVNs(params: VxeTableDefines.CellRenderHeaderParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }, content: VNode | VNode[]) { const vns = [renderTitlePrefixIcon(params), renderHeaderCellDragIcon(params), ...(XEUtils.isArray(content) ? content : [content]), renderTitleSuffixIcon(params)] return vns } function getRenderDefaultColumnTitle(column: VxeTableDefines.ColumnInfo, content: VxeComponentSlotType | VxeComponentSlotType[]) { if (column.type === 'html' && XEUtils.isString(content)) { return h('span', { key: 'ch', innerHTML: content }) } return h( 'span', { key: 'ct' }, getSlotVNs(content) ) } function renderTitleContent(params: VxeTableDefines.CellRenderHeaderParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }, content: VxeComponentSlotType | VxeComponentSlotType[]) { const { $table, column } = params const tableProps = $table.props const tableReactData = $table.reactData const { computeHeaderTooltipOpts } = $table.getComputeMaps() const { showHeaderOverflow: allColumnHeaderOverflow } = tableProps const { isRowGroupStatus } = tableReactData const { showHeaderOverflow, slots } = column const titleSlot = slots ? slots.title : null const headerTooltipOpts = computeHeaderTooltipOpts.value const showAllTip = headerTooltipOpts.showAll const headOverflow = XEUtils.eqNull(showHeaderOverflow) ? allColumnHeaderOverflow : showHeaderOverflow const showTitle = (headOverflow === true ? headerTooltipOpts.mode : headOverflow) === 'title' const showTooltip = (headOverflow === true ? headerTooltipOpts.mode : headOverflow) === 'tooltip' const ons: Record = {} if (showTitle || showTooltip || showAllTip) { ons.onMouseenter = (evnt: MouseEvent) => { if (tableReactData.isDragResize) { return } if (showTitle) { updateCellTitle(evnt.currentTarget, column) } else if (showTooltip || showAllTip) { $table.triggerHeaderTooltipEvent(evnt, params) } } } if (showTooltip || showAllTip) { ons.onMouseleave = (evnt: MouseEvent) => { if (tableReactData.isDragResize) { return } if (showTooltip || showAllTip) { $table.handleTargetLeaveEvent(evnt) } } } const titleVN = getRenderDefaultColumnTitle(column, content) return [ h( 'span', { class: 'vxe-cell--title', ...ons }, isRowGroupStatus && column.aggFunc && $table.getPivotTableAggregateRenderColTitles ? $table.getPivotTableAggregateRenderColTitles(column, titleVN) : titleSlot ? $table.callSlot(titleSlot, params) : [titleVN] ) ] } function getFooterContent(params: VxeTableDefines.CellRenderFooterParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }) { const { $table, column, row } = params const tableProps = $table.props const { editConfig } = tableProps const { slots, editRender, cellRender } = column const footerSlot = slots ? slots.footer : null if (footerSlot) { return $table.callSlot(footerSlot, params) } const isEnableEdit = editConfig && isEnableConf(editConfig) const editRenderOpts = isEnableEdit && isEnableConf(editRender) ? editRender : null const cellRenderOpts = isEnableConf(cellRender) ? cellRender : null const renderOpts = editRenderOpts || cellRenderOpts const itemValue = $table.getFooterCellLabel(row, column) if (renderOpts) { const { computeRendererOpts } = $table.getComputeMaps() const rendererOpts = computeRendererOpts.value const compConf = renderOpts.name ? rendererOpts[renderOpts.name] || renderer.get(renderOpts.name) : null if (compConf) { const rtFooter = compConf.renderTableFooter || compConf.renderFooter if (rtFooter) { const footParams = Object.assign(params, { cellValue: itemValue, itemValue }) return getSlotVNs(rtFooter(renderOpts, footParams)) } } } return [ h( 'span', { class: 'vxe-cell--label' }, formatText(itemValue, 1) ) ] } function getDefaultCellLabel(params: VxeTableDefines.CellRenderBodyParams) { const { $table, row, column } = params return formatText($table.getCellLabel(row, column), 1) } function renderCellHandle( params: VxeTableDefines.CellRenderBodyParams & { $table: VxeTableConstructor & VxeTablePrivateMethods } ) { const { column, row, $table } = params const tableProps = $table.props const tableReactData = $table.reactData const { isRowGroupStatus } = tableReactData const { editConfig } = tableProps const { type, treeNode, rowGroupNode, editRender } = column const { computeEditOpts, computeCheckboxOpts, computeAggregateOpts } = $table.getComputeMaps() const aggregateOpts = computeAggregateOpts.value const { mode } = aggregateOpts const checkboxOpts = computeCheckboxOpts.value const editOpts = computeEditOpts.value const isDeepCell = treeNode || (isRowGroupStatus && (mode === 'column' ? column.field === row.groupField : rowGroupNode)) switch (type) { case 'seq': return isDeepCell ? Cell.renderDeepIndexCell(params) : Cell.renderSeqCell(params) case 'radio': return isDeepCell ? Cell.renderDeepRadioCell(params) : Cell.renderRadioCell(params) case 'checkbox': return checkboxOpts.checkField ? (isDeepCell ? Cell.renderDeepSelectionCellByProp(params) : Cell.renderCheckboxCellByProp(params)) : isDeepCell ? Cell.renderDeepSelectionCell(params) : Cell.renderCheckboxCell(params) case 'expand': return Cell.renderExpandCell(params) case 'html': return isDeepCell ? Cell.renderDeepHTMLCell(params) : Cell.renderHTMLCell(params) } const isEnableEdit = editConfig && isEnableConf(editConfig) const editRenderOpts = isEnableEdit && isEnableConf(editRender) ? editRender : null if (editRenderOpts) { return editOpts.mode === 'cell' ? (isDeepCell ? Cell.renderDeepCellEdit(params) : Cell.renderCellEdit(params)) : isDeepCell ? Cell.renderDeepRowEdit(params) : Cell.renderRowEdit(params) } return isDeepCell ? Cell.renderDeepCell(params) : Cell.renderDefaultCell(params) } function renderHeaderHandle( params: VxeTableDefines.CellRenderHeaderParams & { $table: VxeTableConstructor & VxeTablePrivateMethods } ) { const { column, $table } = params const tableProps = $table.props const { editConfig } = tableProps const { type, filters, sortable, editRender, slots } = column // 兼容已废弃方式 if (getConfig().tableHeadeSlotToTitleSlot !== 'obsolete') { const headerSlot = slots ? slots.header : null if (headerSlot) { return renderTitleContent(params, $table.callSlot(headerSlot, params)) } } switch (type) { case 'seq': return Cell.renderSeqHeader(params) case 'radio': return Cell.renderRadioHeader(params) case 'checkbox': return Cell.renderCheckboxHeader(params) case 'html': if (filters && sortable) { return Cell.renderSortAndFilterHeader(params) } else if (sortable) { return Cell.renderSortHeader(params) } else if (filters) { return Cell.renderFilterHeader(params) } break } const isEnableEdit = editConfig && isEnableConf(editConfig) const editRenderOpts = isEnableEdit && isEnableConf(editRender) ? editRender : null if (editRenderOpts) { return Cell.renderEditHeader(params) } else if (filters && sortable) { return Cell.renderSortAndFilterHeader(params) } else if (sortable) { return Cell.renderSortHeader(params) } else if (filters) { return Cell.renderFilterHeader(params) } return Cell.renderDefaultHeader(params) } function renderFooterHandle( params: VxeTableDefines.CellRenderFooterParams & { $table: VxeTableConstructor & VxeTablePrivateMethods } ) { return Cell.renderDefaultFooter(params) } export const Cell = { createColumn($xeTable: VxeTableConstructor & VxeTablePrivateMethods, columnOpts: VxeTableDefines.ColumnOptions | VxeTableDefines.ColumnInfo) { const { type } = columnOpts const renConfs: any = { renderHeader: renderHeaderHandle, renderCell: renderCellHandle, renderFooter: renderFooterHandle } if (type === 'expand') { renConfs.renderData = Cell.renderExpandData } return createColumn($xeTable, columnOpts, renConfs) }, /** * 列头标题 */ renderHeaderTitle(params: VxeTableDefines.CellRenderHeaderParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }) { const { $table, column } = params const tableProps = $table.props const { editConfig } = tableProps const { slots, editRender, cellRender } = column const isEnableEdit = editConfig && isEnableConf(editConfig) const editRenderOpts = isEnableEdit && isEnableConf(editRender) ? editRender : null const cellRenderOpts = isEnableConf(cellRender) ? cellRender : null const renderOpts = editRenderOpts || cellRenderOpts // 兼容已废弃方式 if (getConfig().tableHeadeSlotToTitleSlot === 'obsolete') { const headerSlot = slots ? slots.header : null if (headerSlot) { return renderTitleContent(params, $table.callSlot(headerSlot, params)) } } if (renderOpts) { const { computeRendererOpts } = $table.getComputeMaps() const rendererOpts = computeRendererOpts.value const compConf = renderOpts.name ? rendererOpts[renderOpts.name] || renderer.get(renderOpts.name) : null if (compConf) { const rtHeader = compConf.renderTableHeader || compConf.renderHeader if (rtHeader) { return renderTitleContent(params, getSlotVNs(rtHeader(renderOpts, params))) } } } return renderTitleContent(params, $table.getHeaderCellLabel(column)) }, renderDefaultHeader(params: VxeTableDefines.CellRenderHeaderParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }) { return renderHeaderCellBaseVNs(params, Cell.renderHeaderTitle(params)) }, renderDefaultCell(params: VxeTableDefines.CellRenderBodyParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }) { const { $table, row, column } = params const tableProps = $table.props const tableReactData = $table.reactData const tableInternalData = $table.internalData const { isRowGroupStatus } = tableReactData const { editConfig } = tableProps const { field, slots, editRender, cellRender, rowGroupNode, aggFunc } = column const isEnableEdit = editConfig && isEnableConf(editConfig) const editRenderOpts = isEnableEdit && isEnableConf(editRender) ? editRender : null const cellRenderOpts = isEnableConf(cellRender) ? cellRender : null const defaultSlot = slots ? slots.default : null const gcSlot = slots ? slots.groupContent || slots['group-content'] : null const gvSlot = slots ? slots.groupValues || slots['group-values'] : null let cellValue: string | number | null = '' if (isRowGroupStatus && field && row.isAggregate) { const aggRow: VxeTableDefines.AggregateRowInfo = row const { fullColumnFieldData } = tableInternalData const { computeAggregateOpts } = $table.getComputeMaps() const aggregateOpts = computeAggregateOpts.value const { mode, showTotal, totalMethod, countFields, contentMethod, formatValuesMethod, mapChildrenField } = aggregateOpts const aggData = aggRow.aggData const currAggData = aggData ? aggData[field] : null const groupField = aggRow.groupField const groupContent = aggRow.groupContent const childList = mapChildrenField ? aggRow[mapChildrenField] || [] : [] const childCount = aggRow.childCount const colRest = fullColumnFieldData[groupField] || {} const ctParams = { $table, groupField, groupColumn: (colRest ? colRest.column : null) as VxeTableDefines.ColumnInfo, column, groupValue: groupContent, childList, childCount, aggValue: null as any, /** * 已废弃 * @deprecated */ children: childList, /** * 已废弃 * @deprecated */ totalValue: childCount } if (mode === 'column' ? field === aggRow.groupField : rowGroupNode) { cellValue = groupContent if (contentMethod) { cellValue = `${contentMethod(ctParams)}` } if (showTotal) { cellValue = getI18n('vxe.table.rowGroupContentTotal', [cellValue, totalMethod ? totalMethod(ctParams) : childCount, childCount]) } if (gcSlot) { return renderCellBaseVNs(params, $table.callSlot(gcSlot, Object.assign({ groupField, groupContent, childList, childCount }, params))) } } else if ($table.getPivotTableAggregateCellAggValue) { cellValue = $table.getPivotTableAggregateCellAggValue(params) ctParams.aggValue = cellValue if (gvSlot) { return renderCellBaseVNs(params, $table.callSlot(gvSlot, Object.assign({ groupField, groupContent, childList, childCount }, params, ctParams))) } } else if (aggFunc === true || (countFields && countFields.includes(field))) { cellValue = currAggData ? currAggData.value : childCount ctParams.aggValue = cellValue if (formatValuesMethod) { cellValue = formatValuesMethod(ctParams) } if (gvSlot) { return renderCellBaseVNs(params, $table.callSlot(gvSlot, Object.assign({ groupField, groupContent, childList, childCount }, params, ctParams))) } } } else { if (defaultSlot) { return renderCellBaseVNs(params, $table.callSlot(defaultSlot, params)) } const { computeRendererOpts } = $table.getComputeMaps() const rendererOpts = computeRendererOpts.value // 如果是编辑模式-查看:slot default > formatter > cellRender.renderTableDefault > editRender.renderTableCell > editRender.renderTableDefault > cellRender.tableCellFormatter > editRender.tableCellFormatter > field // 如果是查看表格:slot default > formatter > cellRender.renderTableDefault > cellRender.tableCellFormatter > field const cellCompConf = cellRenderOpts && cellRenderOpts.name ? rendererOpts[cellRenderOpts.name] || renderer.get(cellRenderOpts.name) : null if (cellRenderOpts) { const cellDefaultRenderFn = cellCompConf ? cellCompConf.renderTableDefault || cellCompConf.renderDefault : null if (cellDefaultRenderFn && cellRenderOpts) { return renderCellBaseVNs(params, getSlotVNs(cellDefaultRenderFn(cellRenderOpts, Object.assign({ $type: editRenderOpts ? 'edit' : 'cell' }, params)))) } } if (editRenderOpts) { const editCompConf = editRenderOpts && editRenderOpts.name ? rendererOpts[editRenderOpts.name] || renderer.get(editRenderOpts.name) : null const editCellRenderFn = editCompConf ? editCompConf.renderTableCell || editCompConf.renderCell || editCompConf.renderTableDefault || editCompConf.renderDefault : null if (editCellRenderFn) { return renderCellBaseVNs(params, getSlotVNs(editCellRenderFn(editRenderOpts, Object.assign({ $type: editRenderOpts ? 'edit' : 'cell' }, params)))) } } // 如果是编辑模式-查看:cellRender.tableCellFormatter > editRender.tableCellFormatter > field // 如果是查看表格:cellRender.tableCellFormatter > field cellValue = $table.getCellLabel(row, column) } const cellPlaceholder = editRenderOpts ? editRenderOpts.placeholder : '' return renderCellBaseVNs(params, [ h( 'span', { class: 'vxe-cell--label' }, [ // 如果设置占位符 editRenderOpts && eqEmptyValue(cellValue) ? h( 'span', { class: 'vxe-cell--placeholder' }, formatText(getFuncText(cellPlaceholder), 1) ) : h('span', formatText(cellValue, 1)) ] ) ]) }, renderDeepCell(params: VxeTableDefines.CellRenderBodyParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }) { return Cell.renderDeepNodeBtn(params, Cell.renderDefaultCell(params) as VNode[]) }, renderDefaultFooter(params: VxeTableDefines.CellRenderFooterParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }) { return getFooterContent(params) }, /** * 行分组 */ renderRowGroupBtn(params: VxeTableDefines.CellRenderBodyParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }, cellVNodes: VxeComponentSlotType[]) { const { $table } = params const tableReactData = $table.reactData const tableInternalData = $table.internalData const { row, level } = params const { computeAggregateOpts } = $table.getComputeMaps() const { rowGroupExpandedFlag } = tableReactData const { rowGroupExpandedMaps } = tableInternalData const aggregateOpts = computeAggregateOpts.value const { mode, padding, indent, showIcon, iconOpen, iconClose } = aggregateOpts const rowid = getRowid($table, row) const isExpand = !!rowGroupExpandedFlag && !!rowGroupExpandedMaps[rowid] return h( 'div', { class: [ 'vxe-row-group--tree-node', { 'is--expanded': isExpand } ], style: mode !== 'column' && padding && indent ? { paddingLeft: `${level * indent}px` } : undefined }, [ showIcon && row.isAggregate ? h( 'span', { class: 'vxe-row-group--node-btn', onClick(evnt: MouseEvent) { $table.triggerRowGroupExpandEvent(evnt, params) } }, [ h('i', { class: isExpand ? iconOpen || getIcon().TABLE_ROW_GROUP_OPEN : iconClose || getIcon().TABLE_ROW_GROUP_CLOSE }) ] ) : renderEmptyElement($table), h( 'div', { class: 'vxe-row-group-cell' }, cellVNodes ) ] ) }, /** * 树 */ renderTreeNodeBtn(params: VxeTableDefines.CellRenderBodyParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }, cellVNodes: VxeComponentSlotType[]) { const { $table, isHidden } = params const tableReactData = $table.reactData const tableInternalData = $table.internalData const { row, column, level } = params const { slots } = column const iconSlot = slots ? slots.icon : null if (iconSlot) { return $table.callSlot(iconSlot, params) } const { computeTreeOpts } = $table.getComputeMaps() const { treeExpandedFlag } = tableReactData const { fullAllDataRowIdData, treeExpandedMaps, treeExpandLazyLoadedMaps } = tableInternalData const treeOpts = computeTreeOpts.value const { padding, indent, lazy, trigger, visibleMethod, iconLoaded, showIcon, iconOpen, iconClose } = treeOpts const childrenField = treeOpts.children || treeOpts.childrenField const hasChildField = treeOpts.hasChild || treeOpts.hasChildField const rowChilds = row[childrenField] const hasChild = rowChilds && rowChilds.length let hasLazyChilds = false let isActive = false let isLazyLoading = false let isLazyLoaded = false const ons: Record = {} if (!isHidden) { const rowid = getRowid($table, row) isActive = !!treeExpandedFlag && !!treeExpandedMaps[rowid] if (lazy) { const rest = fullAllDataRowIdData[rowid] isLazyLoading = !!treeExpandLazyLoadedMaps[rowid] hasLazyChilds = row[hasChildField] isLazyLoaded = !!rest.treeLoaded } } if (!trigger || trigger === 'default') { ons.onClick = (evnt: MouseEvent) => { $table.triggerTreeExpandEvent(evnt, params) } } return h( 'div', { class: [ 'vxe-cell--tree-node', { 'is--active': isActive } ], style: padding && indent ? { paddingLeft: `${level * indent}px` } : undefined }, [ showIcon && (lazy ? (isLazyLoaded ? hasChild : hasChild || hasLazyChilds) : hasChild) && (!visibleMethod || visibleMethod(params)) ? [ h( 'div', { class: 'vxe-cell--tree-btn', ...ons }, [ h('i', { class: isLazyLoading ? iconLoaded || getIcon().TABLE_TREE_LOADED : isActive ? iconOpen || getIcon().TABLE_TREE_OPEN : iconClose || getIcon().TABLE_TREE_CLOSE }) ] ) ] : null, h( 'div', { class: 'vxe-tree-cell' }, cellVNodes ) ] ) }, /** * 层级节点。 * 行分组、树结构 */ renderDeepNodeBtn(params: VxeTableDefines.CellRenderBodyParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }, cellVNodes: VxeComponentSlotType[]) { const { $table, row, column } = params const { rowGroupNode } = column const tableReactData = $table.reactData const { rowGroupList } = tableReactData if (rowGroupList.length) { const { computeAggregateOpts } = $table.getComputeMaps() const aggregateOpts = computeAggregateOpts.value const { mode } = aggregateOpts if (mode === 'column') { if (row.groupField && column.field === row.groupField) { return [Cell.renderRowGroupBtn(params, cellVNodes)] } return cellVNodes } else if (rowGroupNode) { return [Cell.renderRowGroupBtn(params, cellVNodes)] } } return [Cell.renderTreeNodeBtn(params, cellVNodes)] }, /** * 序号 */ renderSeqHeader(params: VxeTableDefines.CellRenderHeaderParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }) { const { $table, column } = params // 兼容已废弃方式 if (getConfig().tableHeadeSlotToTitleSlot === 'obsolete') { const { slots } = column const headerSlot = slots ? slots.header : null return renderHeaderCellBaseVNs(params, renderTitleContent(params, headerSlot ? $table.callSlot(headerSlot, params) : $table.getHeaderCellLabel(column))) } return renderHeaderCellBaseVNs(params, renderTitleContent(params, $table.getHeaderCellLabel(column))) }, renderSeqCell(params: VxeTableDefines.CellRenderBodyParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }) { const { $table, column } = params const tableProps = $table.props const { treeConfig } = tableProps const { computeSeqOpts } = $table.getComputeMaps() const seqOpts = computeSeqOpts.value const { slots } = column const defaultSlot = slots ? slots.default : null if (defaultSlot) { return renderCellBaseVNs(params, $table.callSlot(defaultSlot, params)) } const { seq } = params const seqMd = seqOpts.seqMethod return renderCellBaseVNs(params, [h('span', `${formatText(seqMd ? seqMd(params) : treeConfig ? seq : (seqOpts.startIndex || 0) + (seq as number), 1)}`)]) }, renderDeepIndexCell(params: VxeTableDefines.CellRenderBodyParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }) { return Cell.renderDeepNodeBtn(params, Cell.renderSeqCell(params) as VNode[]) }, /** * 单选 */ renderRadioHeader(params: VxeTableDefines.CellRenderHeaderParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }) { const { $table, column } = params const { slots } = column const titleSlot = slots ? slots.title : null // 兼容已废弃方式 if (getConfig().tableHeadeSlotToTitleSlot === 'obsolete') { const headerSlot = slots ? slots.header : null return renderHeaderCellBaseVNs( params, renderTitleContent( params, headerSlot ? $table.callSlot(headerSlot, params) : [ h( 'span', { class: 'vxe-radio--label' }, titleSlot ? $table.callSlot(titleSlot, params) : $table.getHeaderCellLabel(column) ) ] ) ) } return renderHeaderCellBaseVNs( params, renderTitleContent(params, [ h( 'span', { class: 'vxe-radio--label' }, titleSlot ? $table.callSlot(titleSlot, params) : $table.getHeaderCellLabel(column) ) ]) ) }, renderRadioCell(params: VxeTableDefines.CellRenderBodyParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }) { const { $table, column, isHidden } = params const tableReactData = $table.reactData const { computeRadioOpts } = $table.getComputeMaps() const { selectRadioRow } = tableReactData const radioOpts = computeRadioOpts.value const { slots } = column const { labelField, checkMethod, visibleMethod } = radioOpts const { row } = params const defaultSlot = slots ? slots.default : null const radioSlot = slots ? slots.radio : null const isChecked = $table.eqRow(row, selectRadioRow) const isVisible = !visibleMethod || visibleMethod({ $table, row }) let isDisabled = !!checkMethod let ons if (!isHidden) { ons = { onClick(evnt: Event) { if (!isDisabled && isVisible) { $table.triggerRadioRowEvent(evnt, params) } } } if (checkMethod) { isDisabled = !checkMethod({ $table, row }) } } const radioParams = { ...params, checked: isChecked, disabled: isDisabled, visible: isVisible } if (radioSlot) { return renderCellBaseVNs(params, $table.callSlot(radioSlot, radioParams)) } const radioVNs: VNode[] = [] if (isVisible) { radioVNs.push( h('span', { class: ['vxe-radio--icon', isChecked ? getIcon().TABLE_RADIO_CHECKED : isDisabled ? getIcon().TABLE_RADIO_DISABLED_UNCHECKED : getIcon().TABLE_RADIO_UNCHECKED] }) ) } if (defaultSlot || labelField) { radioVNs.push( h( 'span', { class: 'vxe-radio--label' }, defaultSlot ? $table.callSlot(defaultSlot, radioParams) : XEUtils.get(row, labelField as string) ) ) } return renderCellBaseVNs(params, [ h( 'span', { class: [ 'vxe-cell--radio', { 'is--checked': isChecked, 'is--disabled': isDisabled } ], ...ons }, radioVNs ) ]) }, renderDeepRadioCell(params: VxeTableDefines.CellRenderBodyParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }) { return Cell.renderDeepNodeBtn(params, Cell.renderRadioCell(params)) }, /** * 多选 */ renderCheckboxHeader(params: VxeTableDefines.CellRenderHeaderParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }) { const { $table, column, isHidden } = params const tableReactData = $table.reactData const { computeIsAllCheckboxDisabled, computeCheckboxOpts } = $table.getComputeMaps() const { isAllSelected: isAllCheckboxSelected, isIndeterminate: isAllCheckboxIndeterminate } = tableReactData const isAllCheckboxDisabled = computeIsAllCheckboxDisabled.value const { slots } = column const titleSlot = slots ? slots.title : null const checkboxOpts = computeCheckboxOpts.value const { checkStrictly, showHeader, headerTitle } = checkboxOpts const colTitle = $table.getHeaderCellLabel(column) const ons: Record = {} if (!isHidden) { ons.onClick = (evnt: MouseEvent) => { if (!isAllCheckboxDisabled) { $table.triggerCheckAllEvent(evnt, !isAllCheckboxSelected) } } } const checkboxParams = { ...params, checked: isAllCheckboxSelected, disabled: isAllCheckboxDisabled, indeterminate: isAllCheckboxIndeterminate } // 兼容已废弃方式 if (getConfig().tableHeadeSlotToTitleSlot === 'obsolete') { const headerSlot = slots ? slots.header : null if (headerSlot) { return renderHeaderCellBaseVNs(params, renderTitleContent(checkboxParams, $table.callSlot(headerSlot, checkboxParams))) } } if (checkStrictly ? !showHeader : showHeader === false) { return renderHeaderCellBaseVNs( params, renderTitleContent(checkboxParams, [ h( 'span', { class: 'vxe-checkbox--label' }, titleSlot ? $table.callSlot(titleSlot, checkboxParams) : colTitle ) ]) ) } return renderHeaderCellBaseVNs( params, renderTitleContent(checkboxParams, [ h( 'span', { class: [ 'vxe-cell--checkbox', { 'is--checked': isAllCheckboxSelected, 'is--disabled': isAllCheckboxDisabled, 'is--indeterminate': isAllCheckboxIndeterminate } ], title: XEUtils.eqNull(headerTitle) ? getI18n('vxe.table.allTitle') : `${headerTitle || ''}`, ...ons }, [ h('span', { class: ['vxe-checkbox--icon', isAllCheckboxIndeterminate ? getIcon().TABLE_CHECKBOX_INDETERMINATE : isAllCheckboxSelected ? getIcon().TABLE_CHECKBOX_CHECKED : isAllCheckboxDisabled ? getIcon().TABLE_CHECKBOX_DISABLED_UNCHECKED : getIcon().TABLE_CHECKBOX_UNCHECKED] }) ].concat( titleSlot || colTitle ? [ h( 'span', { class: 'vxe-checkbox--label' }, titleSlot ? $table.callSlot(titleSlot, checkboxParams) : colTitle ) ] : [] ) ) ]) ) }, renderCheckboxCell(params: VxeTableDefines.CellRenderBodyParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }) { const { $table, row, column, isHidden } = params const tableProps = $table.props const tableReactData = $table.reactData const tableInternalData = $table.internalData const { treeConfig } = tableProps const { updateCheckboxFlag, isRowGroupStatus } = tableReactData const { selectCheckboxMaps, treeIndeterminateRowMaps } = tableInternalData const { computeCheckboxOpts, computeAggregateOpts } = $table.getComputeMaps() const aggregateOpts = computeAggregateOpts.value const { mapChildrenField } = aggregateOpts const checkboxOpts = computeCheckboxOpts.value const { labelField, checkMethod, visibleMethod } = checkboxOpts const { slots } = column const defaultSlot = slots ? slots.default : null const checkboxSlot = slots ? slots.checkbox : null let indeterminate = false let isChecked = false let isVisible = true let isDisabled = false const ons: Record = {} if (!isHidden) { const rowid = getRowid($table, row) isChecked = !!updateCheckboxFlag && !!selectCheckboxMaps[rowid] if (checkMethod && isRowGroupStatus && $table.isAggregateRecord(row)) { const childList: any[] = row[mapChildrenField || ''] if (!childList || !childList.length || childList.every((item) => !checkMethod({ $table, row: item }))) { isDisabled = true } } else { isVisible = !visibleMethod || visibleMethod({ $table, row }) isDisabled = checkMethod ? !checkMethod({ $table, row }) : !!checkMethod } if (treeConfig || isRowGroupStatus) { indeterminate = !!treeIndeterminateRowMaps[rowid] } ons.onClick = (evnt: MouseEvent) => { if (!isDisabled && isVisible) { $table.triggerCheckRowEvent(evnt, params, !isChecked) } } } const checkboxParams = { ...params, checked: isChecked, disabled: isDisabled, visible: isVisible, indeterminate } if (checkboxSlot) { return renderCellBaseVNs(params, $table.callSlot(checkboxSlot, checkboxParams)) } const checkVNs: VNode[] = [] if (isVisible) { checkVNs.push( h('span', { class: ['vxe-checkbox--icon', indeterminate ? getIcon().TABLE_CHECKBOX_INDETERMINATE : isChecked ? getIcon().TABLE_CHECKBOX_CHECKED : isDisabled ? getIcon().TABLE_CHECKBOX_DISABLED_UNCHECKED : getIcon().TABLE_CHECKBOX_UNCHECKED] }) ) } if (defaultSlot || labelField) { checkVNs.push( h( 'span', { class: 'vxe-checkbox--label' }, defaultSlot ? $table.callSlot(defaultSlot, checkboxParams) : XEUtils.get(row, labelField as string) ) ) } return renderCellBaseVNs(params, [ h( 'span', { class: [ 'vxe-cell--checkbox', { 'is--checked': isChecked, 'is--disabled': isDisabled, 'is--indeterminate': indeterminate, 'is--hidden': !isVisible } ], ...ons }, checkVNs ) ]) }, renderDeepSelectionCell(params: VxeTableDefines.CellRenderBodyParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }) { return Cell.renderDeepNodeBtn(params, Cell.renderCheckboxCell(params)) }, renderCheckboxCellByProp(params: VxeTableDefines.CellRenderBodyParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }) { const { $table, row, column, isHidden } = params const tableProps = $table.props const tableReactData = $table.reactData const tableInternalData = $table.internalData const { treeConfig } = tableProps const { updateCheckboxFlag, isRowGroupStatus } = tableReactData const { treeIndeterminateRowMaps } = tableInternalData const { computeCheckboxOpts, computeAggregateOpts } = $table.getComputeMaps() const aggregateOpts = computeAggregateOpts.value const { mapChildrenField } = aggregateOpts const checkboxOpts = computeCheckboxOpts.value const { labelField, checkField, checkMethod, visibleMethod } = checkboxOpts const indeterminateField = checkboxOpts.indeterminateField || checkboxOpts.halfField const { slots } = column const defaultSlot = slots ? slots.default : null const checkboxSlot = slots ? slots.checkbox : null let indeterminate = false let isChecked = false let isVisible = true let isDisabled = false const ons: Record = {} if (!isHidden) { const rowid = getRowid($table, row) isChecked = !!updateCheckboxFlag && XEUtils.get(row, checkField) if (checkMethod && isRowGroupStatus && $table.isAggregateRecord(row)) { const childList: any[] = row[mapChildrenField || ''] if (!childList || !childList.length || childList.every((item) => !checkMethod({ $table, row: item }))) { isDisabled = true } } else { isVisible = !visibleMethod || visibleMethod({ $table, row }) isDisabled = checkMethod ? !checkMethod({ $table, row }) : !!checkMethod } if (treeConfig || isRowGroupStatus) { indeterminate = !!treeIndeterminateRowMaps[rowid] } ons.onClick = (evnt: MouseEvent) => { if (!isDisabled && isVisible) { $table.triggerCheckRowEvent(evnt, params, !isChecked) } } } const checkboxParams = { ...params, checked: isChecked, disabled: isDisabled, visible: isVisible, indeterminate } if (checkboxSlot) { return renderCellBaseVNs(params, $table.callSlot(checkboxSlot, checkboxParams)) } const checkVNs: VNode[] = [] if (isVisible) { checkVNs.push( h('span', { class: ['vxe-checkbox--icon', indeterminate ? getIcon().TABLE_CHECKBOX_INDETERMINATE : isChecked ? getIcon().TABLE_CHECKBOX_CHECKED : isDisabled ? getIcon().TABLE_CHECKBOX_DISABLED_UNCHECKED : getIcon().TABLE_CHECKBOX_UNCHECKED] }) ) if (defaultSlot || labelField) { checkVNs.push( h( 'span', { class: 'vxe-checkbox--label' }, defaultSlot ? $table.callSlot(defaultSlot, checkboxParams) : XEUtils.get(row, labelField as string) ) ) } } return renderCellBaseVNs(params, [ h( 'span', { class: [ 'vxe-cell--checkbox', { 'is--checked': isChecked, 'is--disabled': isDisabled, 'is--indeterminate': indeterminateField && !isChecked ? row[indeterminateField] : indeterminate, 'is--hidden': !isVisible } ], ...ons }, checkVNs ) ]) }, renderDeepSelectionCellByProp(params: VxeTableDefines.CellRenderBodyParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }) { return Cell.renderDeepNodeBtn(params, Cell.renderCheckboxCellByProp(params)) }, /** * 展开行 */ renderExpandCell(params: VxeTableDefines.CellRenderBodyParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }) { const { $table, isHidden, row, column } = params const tableReactData = $table.reactData const tableInternalData = $table.internalData const { isRowGroupStatus } = tableReactData const { rowExpandedMaps, rowExpandLazyLoadedMaps } = tableInternalData const { computeExpandOpts } = $table.getComputeMaps() const expandOpts = computeExpandOpts.value const { lazy, labelField, iconLoaded, showIcon, iconOpen, iconClose, visibleMethod } = expandOpts const { slots } = column const defaultSlot = slots ? slots.default : null const iconSlot = slots ? slots.icon : null let isActive = false let isLazyLoading = false if (isRowGroupStatus && row.isAggregate) { return renderCellBaseVNs(params, []) } if (iconSlot) { return renderCellBaseVNs(params, $table.callSlot(iconSlot, params)) } if (!isHidden) { const rowid = getRowid($table, row) isActive = !!rowExpandedMaps[rowid] if (lazy) { isLazyLoading = !!rowExpandLazyLoadedMaps[rowid] } } return renderCellBaseVNs(params, [ showIcon && (!visibleMethod || visibleMethod(params)) ? h( 'div', { class: [ 'vxe-table--expanded', { 'is--active': isActive } ] }, [ h( 'span', { class: 'vxe-table--expand-btn', onMousedown(evnt) { evnt.stopPropagation() }, onClick(evnt: MouseEvent) { $table.triggerRowExpandEvent(evnt, params) } }, [ h('i', { class: isLazyLoading ? iconLoaded || getIcon().TABLE_EXPAND_LOADED : isActive ? iconOpen || getIcon().TABLE_EXPAND_OPEN : iconClose || getIcon().TABLE_EXPAND_CLOSE }) ] ) ] ) : renderEmptyElement($table), defaultSlot || labelField ? h( 'div', { class: 'vxe-table--expand-label' }, defaultSlot ? $table.callSlot(defaultSlot, params) : XEUtils.get(row, labelField as string) ) : renderEmptyElement($table) ]) }, renderExpandData(params: VxeTableDefines.CellRenderDataParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }) { const { $table, column } = params const { slots, contentRender } = column const contentSlot = slots ? slots.content : null if (contentSlot) { return $table.callSlot(contentSlot, params) } if (contentRender) { const { computeRendererOpts } = $table.getComputeMaps() const rendererOpts = computeRendererOpts.value const compConf = contentRender.name ? rendererOpts[contentRender.name] || renderer.get(contentRender.name) : null if (compConf) { const rtExpand = compConf.renderTableExpand || compConf.renderExpand if (rtExpand) { return getSlotVNs(rtExpand(contentRender, params)) } } } return [] }, /** * HTML 标签 */ renderHTMLCell(params: VxeTableDefines.CellRenderBodyParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }) { const { $table, column } = params const { slots } = column const defaultSlot = slots ? slots.default : null if (defaultSlot) { return renderCellBaseVNs(params, $table.callSlot(defaultSlot, params)) } return renderCellBaseVNs(params, [ h('span', { class: 'vxe-cell--html', innerHTML: getDefaultCellLabel(params) }) ]) }, renderDeepHTMLCell(params: VxeTableDefines.CellRenderBodyParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }) { return Cell.renderDeepNodeBtn(params, Cell.renderHTMLCell(params)) }, /** * 排序和筛选 */ renderSortAndFilterHeader(params: VxeTableDefines.CellRenderHeaderParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }) { return renderHeaderCellBaseVNs(params, Cell.renderHeaderTitle(params).concat(Cell.renderSortIcon(params).concat(Cell.renderFilterIcon(params)))) }, /** * 排序 */ renderSortHeader(params: VxeTableDefines.CellRenderHeaderParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }) { return renderHeaderCellBaseVNs(params, Cell.renderHeaderTitle(params).concat(Cell.renderSortIcon(params))) }, renderSortIcon(params: (VxeTableDefines.CellRenderHeaderParams | VxeTableDefines.CellRenderHeaderParams) & { $table: VxeTableConstructor & VxeTablePrivateMethods }) { const { $table, column } = params const { computeSortOpts } = $table.getComputeMaps() const sortOpts = computeSortOpts.value const { showIcon, allowBtn, ascTitle, descTitle, iconLayout, iconAsc, iconDesc, iconVisibleMethod } = sortOpts const { order, slots } = column if (showIcon && (!iconVisibleMethod || iconVisibleMethod(params))) { const sortSlot = slots ? slots.sort : null return sortSlot ? (getSlotVNs($table.callSlot(sortSlot, params)) as VNode[]) : [ h( 'span', { class: ['vxe-cell--sort', `vxe-cell--sort-${iconLayout}-layout`] }, [ h('i', { class: [ 'vxe-sort--asc-btn', iconAsc || getIcon().TABLE_SORT_ASC, { 'sort--active': order === 'asc' } ], title: XEUtils.eqNull(ascTitle) ? getI18n('vxe.table.sortAsc') : `${ascTitle || ''}`, onClick: allowBtn ? (evnt: Event) => { evnt.stopPropagation() $table.triggerSortEvent(evnt, column, 'asc') } : undefined }), h('i', { class: [ 'vxe-sort--desc-btn', iconDesc || getIcon().TABLE_SORT_DESC, { 'sort--active': order === 'desc' } ], title: XEUtils.eqNull(descTitle) ? getI18n('vxe.table.sortDesc') : `${descTitle || ''}`, onClick: allowBtn ? (evnt: Event) => { evnt.stopPropagation() $table.triggerSortEvent(evnt, column, 'desc') } : undefined }) ] ) ] } return [] }, /** * 筛选 */ renderFilterHeader(params: VxeTableDefines.CellRenderHeaderParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }) { return renderHeaderCellBaseVNs(params, Cell.renderHeaderTitle(params).concat(Cell.renderFilterIcon(params))) }, renderFilterIcon(params: VxeTableDefines.CellRenderHeaderParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }) { const { $table, column, hasFilter } = params const tableReactData = $table.reactData const { filterStore } = tableReactData const { computeFilterOpts } = $table.getComputeMaps() const filterOpts = computeFilterOpts.value const { showIcon, iconNone, iconMatch, iconVisibleMethod } = filterOpts if (showIcon && (!iconVisibleMethod || iconVisibleMethod(params))) { return [ h( 'span', { class: [ 'vxe-cell--filter', { 'is--active': filterStore.visible && filterStore.column === column } ], onClick(evnt) { if ($table.triggerFilterEvent) { $table.triggerFilterEvent(evnt, params.column, params) } } }, [ h('i', { class: ['vxe-filter--btn', hasFilter ? iconMatch || getIcon().TABLE_FILTER_MATCH : iconNone || getIcon().TABLE_FILTER_NONE], title: getI18n('vxe.table.filter') }) ] ) ] } return [] }, /** * 可编辑 */ renderEditHeader(params: VxeTableDefines.CellRenderHeaderParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }) { const { $table, column } = params const tableProps = $table.props const { computeEditOpts } = $table.getComputeMaps() const { editConfig, editRules } = tableProps const editOpts = computeEditOpts.value const { sortable, filters, editRender } = column const isEnableEdit = editConfig && isEnableConf(editConfig) const editRenderOpts = isEnableEdit && isEnableConf(editRender) ? editRender : null let isRequired = false if (editRules) { const columnRules = column.rules ? column.rules : XEUtils.get(editRules, column.field) if (columnRules) { isRequired = columnRules.some((rule) => rule.required) } } let editIconVNs: VNode[] = [] if (isEnableEdit) { const { showAsterisk, showIcon, icon } = editOpts editIconVNs = [ isRequired && showAsterisk ? h( 'span', { class: 'vxe-cell--required-icon' }, [h('i')] ) : renderEmptyElement($table), editRenderOpts && showIcon ? h( 'span', { class: 'vxe-cell--edit-icon' }, XEUtils.isFunction(icon) ? getSlotVNs(icon({})) : [ h('i', { class: icon || getIcon().TABLE_EDIT }) ] ) : renderEmptyElement($table) ] } return renderHeaderCellBaseVNs( params, editIconVNs .concat(Cell.renderHeaderTitle(params)) .concat(sortable ? Cell.renderSortIcon(params) : []) .concat(filters ? Cell.renderFilterIcon(params) : []) ) }, // 行格编辑模式 renderRowEdit(params: VxeTableDefines.CellRenderBodyParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }) { const { $table, column } = params const tableProps = $table.props const { editConfig } = tableProps const tableReactData = $table.reactData const { editStore } = tableReactData const { actived } = editStore const { editRender } = column const isEnableEdit = editConfig && isEnableConf(editConfig) const editRenderOpts = isEnableEdit && isEnableConf(editRender) ? editRender : null return Cell.runRenderer(params, !!(editRenderOpts && actived && actived.row === params.row)) }, renderDeepRowEdit(params: VxeTableDefines.CellRenderBodyParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }) { return Cell.renderDeepNodeBtn(params, Cell.renderRowEdit(params) as VNode[]) }, // 单元格编辑模式 renderCellEdit(params: VxeTableDefines.CellRenderBodyParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }) { const { $table, column } = params const tableProps = $table.props const { editConfig } = tableProps const tableReactData = $table.reactData const { editStore } = tableReactData const { actived } = editStore const { editRender } = column const isEnableEdit = editConfig && isEnableConf(editConfig) const editRenderOpts = isEnableEdit && isEnableConf(editRender) ? editRender : null return Cell.runRenderer(params, !!(editRenderOpts && actived && actived.row === params.row && actived.column === params.column)) }, renderDeepCellEdit(params: VxeTableDefines.CellRenderBodyParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }) { return Cell.renderDeepNodeBtn(params, Cell.renderCellEdit(params) as VNode[]) }, runRenderer(params: VxeTableDefines.CellRenderBodyParams & { $table: VxeTableConstructor & VxeTablePrivateMethods }, isEdit: boolean) { const { $table, row, column } = params const tableProps = $table.props const { editConfig } = tableProps const tableReactData = $table.reactData const { isRowGroupStatus } = tableReactData const { slots, field, editRender, formatter } = column const isEnableEdit = editConfig && isEnableConf(editConfig) const editRenderOpts = isEnableEdit && isEnableConf(editRender) ? editRender : null const defaultSlot = slots ? slots.default : null const gcSlot = slots ? slots.groupContent || slots['group-content'] : null const editSlot = slots ? slots.edit : null const cellParams = Object.assign({ $type: '', isEdit }, params) if (isEdit && editRenderOpts) { cellParams.$type = 'edit' if (editSlot) { return $table.callSlot(editSlot, cellParams) } const { computeRendererOpts } = $table.getComputeMaps() const rendererOpts = computeRendererOpts.value const compConf = editRenderOpts.name ? rendererOpts[editRenderOpts.name] || renderer.get(editRenderOpts.name) : null const rtEdit = compConf ? compConf.renderTableEdit || compConf.renderEdit : null if (rtEdit) { return getSlotVNs(rtEdit(editRenderOpts, cellParams)) } return [] } if (isRowGroupStatus && field && row.isAggregate) { const aggRow: VxeTableDefines.AggregateRowInfo = row const { computeAggregateOpts } = $table.getComputeMaps() const aggregateOpts = computeAggregateOpts.value const { mapChildrenField } = aggregateOpts const groupField = aggRow.groupField const groupContent = aggRow.groupContent const childList = mapChildrenField ? aggRow[mapChildrenField] || [] : [] const childCount = aggRow.childCount if (gcSlot) { return renderCellBaseVNs(params, $table.callSlot(gcSlot, Object.assign({ groupField, groupContent, childList, childCount }, params))) } } else { if (defaultSlot) { return renderCellBaseVNs(params, $table.callSlot(defaultSlot, cellParams)) } } // slot default > formatter if (formatter) { return renderCellBaseVNs(params, [ h( 'span', { class: 'vxe-cell--label' }, getDefaultCellLabel(cellParams) ) ]) } return Cell.renderDefaultCell(cellParams) } } export default Cell