diff --git a/packages/components/table/src/h-helper.ts b/packages/components/table/src/h-helper.ts index d91e807740..0fea1dac39 100644 --- a/packages/components/table/src/h-helper.ts +++ b/packages/components/table/src/h-helper.ts @@ -2,13 +2,7 @@ import { h } from 'vue' import type { TableColumnCtx } from './table-column/defaults' -export function hGutter() { - return h('col', { - name: 'gutter', - }) -} - -export function hColgroup(columns: TableColumnCtx[], hasGutter = false) { +export function hColgroup(columns: TableColumnCtx[]) { return h('colgroup', {}, [ ...columns.map((column) => h('col', { @@ -16,6 +10,5 @@ export function hColgroup(columns: TableColumnCtx[], hasGutter = false) { key: column.id, }) ), - hasGutter && hGutter(), ]) } diff --git a/packages/components/table/src/layout-observer.ts b/packages/components/table/src/layout-observer.ts index 7d7faf2679..cf5b0f2a8a 100644 --- a/packages/components/table/src/layout-observer.ts +++ b/packages/components/table/src/layout-observer.ts @@ -53,12 +53,13 @@ function useLayoutObserver(root: Table) { } const onScrollableChange = (layout: TableLayout) => { - const cols = root.vnode.el.querySelectorAll('colgroup > col[name=gutter]') + const cols = + root.vnode.el?.querySelectorAll('colgroup > col[name=gutter]') || [] for (let i = 0, j = cols.length; i < j; i++) { const col = cols[i] col.setAttribute('width', layout.scrollY.value ? layout.gutterWidth : '0') } - const ths = root.vnode.el.querySelectorAll('th.gutter') + const ths = root.vnode.el?.querySelectorAll('th.gutter') || [] for (let i = 0, j = ths.length; i < j; i++) { const th = ths[i] th.style.width = layout.scrollY.value ? `${layout.gutterWidth}px` : '0' diff --git a/packages/components/table/src/table-body/events-helper.ts b/packages/components/table/src/table-body/events-helper.ts index 9a75a7632e..075f4338da 100644 --- a/packages/components/table/src/table-body/events-helper.ts +++ b/packages/components/table/src/table-body/events-helper.ts @@ -1,15 +1,13 @@ -import { getCurrentInstance, ref, h } from 'vue' +import { ref, h, inject } from 'vue' import debounce from 'lodash/debounce' import { getStyle, hasClass } from '@element-plus/utils/dom' import { createTablePopper, getCell, getColumnByCell } from '../util' - +import { TABLE_INJECTION_KEY } from '../tokens' import type { TableColumnCtx } from '../table-column/defaults' -import type { Table } from '../table/defaults' import type { TableBodyProps } from './defaults' function useEvents(props: Partial>) { - const instance = getCurrentInstance() - const parent = instance.parent as Table + const parent = inject(TABLE_INJECTION_KEY) const tooltipContent = ref('') const tooltipTrigger = ref(h('div')) const handleEvent = (event: Event, row: T, name: string) => { diff --git a/packages/components/table/src/table-body/index.ts b/packages/components/table/src/table-body/index.ts index 13cfdb8ee4..d99d135ddd 100644 --- a/packages/components/table/src/table-body/index.ts +++ b/packages/components/table/src/table-body/index.ts @@ -5,25 +5,25 @@ import { watch, onUnmounted, onUpdated, + inject, } from 'vue' import { isClient } from '@vueuse/core' import { addClass, removeClass } from '@element-plus/utils/dom' import { hColgroup } from '../h-helper' import useLayoutObserver from '../layout-observer' import { removePopper } from '../util' +import { TABLE_INJECTION_KEY } from '../tokens' import useRender from './render-helper' import defaultProps from './defaults' import type { VNode } from 'vue' -import type { DefaultRow, Table } from '../table/defaults' export default defineComponent({ name: 'ElTableBody', props: defaultProps, setup(props) { const instance = getCurrentInstance() - const parent = instance.parent as Table - + const parent = inject(TABLE_INJECTION_KEY) const { wrappedRowRender, tooltipContent, tooltipTrigger } = useRender(props) const { onColumnsChange, onScrollableChange } = useLayoutObserver(parent) diff --git a/packages/components/table/src/table-body/render-helper.ts b/packages/components/table/src/table-body/render-helper.ts index 6316f592b1..b30a8c732a 100644 --- a/packages/components/table/src/table-body/render-helper.ts +++ b/packages/components/table/src/table-body/render-helper.ts @@ -1,19 +1,13 @@ -import { h, getCurrentInstance, computed } from 'vue' +import { h, computed, inject } from 'vue' import { getRowIdentity } from '../util' +import { TABLE_INJECTION_KEY } from '../tokens' import useEvents from './events-helper' import useStyles from './styles-helper' - import type { TableBodyProps } from './defaults' -import type { - RenderRowData, - Table, - TreeNode, - TableProps, -} from '../table/defaults' +import type { RenderRowData, TreeNode, TableProps } from '../table/defaults' function useRender(props: Partial>) { - const instance = getCurrentInstance() - const parent = instance.parent as Table + const parent = inject(TABLE_INJECTION_KEY) const { handleDoubleClick, handleClick, diff --git a/packages/components/table/src/table-body/styles-helper.ts b/packages/components/table/src/table-body/styles-helper.ts index 24f310ec5f..5a98f49a11 100644 --- a/packages/components/table/src/table-body/styles-helper.ts +++ b/packages/components/table/src/table-body/styles-helper.ts @@ -1,16 +1,15 @@ -import { getCurrentInstance } from 'vue' +import { inject } from 'vue' import { getFixedColumnOffset, getFixedColumnsClass, ensurePosition, } from '../util' +import { TABLE_INJECTION_KEY } from '../tokens' import type { TableColumnCtx } from '../table-column/defaults' -import type { Table } from '../table/defaults' import type { TableBodyProps } from './defaults' function useStyles(props: Partial>) { - const instance = getCurrentInstance() - const parent = instance.parent as Table + const parent = inject(TABLE_INJECTION_KEY) const getRowStyle = (row: T, rowIndex: number) => { const rowStyle = parent.props.rowStyle diff --git a/packages/components/table/src/table-footer/index.ts b/packages/components/table/src/table-footer/index.ts index 199e06fc41..6775a0291a 100644 --- a/packages/components/table/src/table-footer/index.ts +++ b/packages/components/table/src/table-footer/index.ts @@ -42,26 +42,18 @@ export default defineComponent({ }, }, setup(props) { - const { hasGutter, getCellClasses, getCellStyles, columns, gutterWidth } = - useStyle(props as TableFooter) + const { getCellClasses, getCellStyles, columns } = useStyle( + props as TableFooter + ) return { getCellClasses, getCellStyles, - hasGutter, - gutterWidth, columns, } }, render() { - const { - hasGutter, - gutterWidth, - columns, - getCellStyles, - getCellClasses, - summaryMethod, - sumText, - } = this + const { columns, getCellStyles, getCellClasses, summaryMethod, sumText } = + this const data = this.store.states.data.value let sums = [] if (summaryMethod) { @@ -109,45 +101,32 @@ export default defineComponent({ border: '0', }, [ - hColgroup(columns, hasGutter), - h( - 'tbody', - { - class: [{ 'has-gutter': hasGutter }], - }, - [ - h('tr', {}, [ - ...columns.map((column, cellIndex) => - h( - 'td', - { - key: cellIndex, - colspan: column.colSpan, - rowspan: column.rowSpan, - class: getCellClasses(columns, cellIndex, hasGutter), - style: getCellStyles(column, cellIndex, hasGutter), - }, - [ - h( - 'div', - { - class: ['cell', column.labelClassName], - }, - [sums[cellIndex]] - ), - ] - ) - ), - hasGutter && - h('td', { - class: 'el-table__fixed-right-patch el-table__cell', - style: { - width: `${gutterWidth}px`, - }, - }), - ]), - ] - ), + hColgroup(columns), + h('tbody', [ + h('tr', {}, [ + ...columns.map((column, cellIndex) => + h( + 'td', + { + key: cellIndex, + colspan: column.colSpan, + rowspan: column.rowSpan, + class: getCellClasses(columns, cellIndex), + style: getCellStyles(column, cellIndex), + }, + [ + h( + 'div', + { + class: ['cell', column.labelClassName], + }, + [sums[cellIndex]] + ), + ] + ) + ), + ]), + ]), ] ) }, diff --git a/packages/components/table/src/table-footer/style-helper.ts b/packages/components/table/src/table-footer/style-helper.ts index 9ef118a8ae..d4936bd8e7 100644 --- a/packages/components/table/src/table-footer/style-helper.ts +++ b/packages/components/table/src/table-footer/style-helper.ts @@ -1,38 +1,16 @@ -import { computed, getCurrentInstance } from 'vue' import { getFixedColumnOffset, getFixedColumnsClass, ensurePosition, - ensureRightFixedStyle, } from '../util' import useMapState from './mapState-helper' -import type { Table } from '../table/defaults' import type { TableColumnCtx } from '../table-column/defaults' import type { TableFooter } from '.' function useStyle(props: TableFooter) { - const instance = getCurrentInstance() - const table = instance.parent as Table - const { columns } = useMapState() - const hasGutter = computed(() => { - return ( - !props.fixed && - table.layout.gutterWidth > 0 && - table.layout.height.value && - table.layout.bodyScrollHeight.value > table.layout.bodyHeight.value - ) - }) - - const gutterWidth = computed(() => { - return table.layout.gutterWidth - }) - const getCellClasses = ( - columns: TableColumnCtx[], - cellIndex: number, - hasGutter: boolean - ) => { + const getCellClasses = (columns: TableColumnCtx[], cellIndex: number) => { const column = columns[cellIndex] const classes = [ 'el-table__cell', @@ -47,31 +25,21 @@ function useStyle(props: TableFooter) { if (!column.children) { classes.push('is-leaf') } - if (hasGutter && cellIndex === columns.length - 1) { - classes.push('last') - } return classes } - const getCellStyles = ( - column: TableColumnCtx, - cellIndex: number, - hasGutter: boolean - ) => { + const getCellStyles = (column: TableColumnCtx, cellIndex: number) => { const fixedStyle = getFixedColumnOffset( cellIndex, column.fixed, props.store ) - ensureRightFixedStyle(fixedStyle, hasGutter) ensurePosition(fixedStyle, 'left') ensurePosition(fixedStyle, 'right') return fixedStyle } return { - hasGutter, - gutterWidth, getCellClasses, getCellStyles, columns, diff --git a/packages/components/table/src/table-header/index.ts b/packages/components/table/src/table-header/index.ts index 222654722d..7b4d4f47f6 100644 --- a/packages/components/table/src/table-header/index.ts +++ b/packages/components/table/src/table-header/index.ts @@ -1,7 +1,6 @@ import { defineComponent, getCurrentInstance, - computed, onMounted, nextTick, ref, @@ -62,18 +61,7 @@ export default defineComponent({ const parent = instance.parent as Table const storeData = parent.store.states const filterPanels = ref({}) - const { tableLayout, onColumnsChange, onScrollableChange } = - useLayoutObserver(parent) - const hasGutter = computed(() => { - return ( - !props.fixed && - tableLayout.gutterWidth > 0 && - tableLayout.bodyScrollHeight.value > tableLayout.bodyHeight.value - ) - }) - const gutterWidth = computed(() => { - return tableLayout.gutterWidth - }) + const { onColumnsChange, onScrollableChange } = useLayoutObserver(parent) onMounted(() => { nextTick(() => { const { prop, order } = props.defaultSort @@ -110,8 +98,6 @@ export default defineComponent({ return { columns: storeData.columns, filterPanels, - hasGutter, - gutterWidth, onColumnsChange, onScrollableChange, columnRows, @@ -134,9 +120,7 @@ export default defineComponent({ const { columns, isGroup, - hasGutter, columnRows, - gutterWidth, getHeaderCellStyle, getHeaderCellClass, getHeaderRowClass, @@ -160,11 +144,11 @@ export default defineComponent({ class: 'el-table__header', }, [ - hColgroup(columns, hasGutter), + hColgroup(columns), h( 'thead', { - class: { 'is-group': isGroup, 'has-gutter': hasGutter }, + class: { 'is-group': isGroup }, }, columnRows.map((subColumns, rowIndex) => h( @@ -174,121 +158,92 @@ export default defineComponent({ key: rowIndex, style: getHeaderRowStyle(rowIndex), }, - subColumns - .map((column, cellIndex) => { - if (column.rowSpan > rowSpan) { - rowSpan = column.rowSpan - } - return h( - 'th', - { - class: getHeaderCellClass( - rowIndex, - cellIndex, - subColumns, - column - ), - colspan: column.colSpan, - key: `${column.id}-thead`, - rowSpan: column.rowSpan, - style: getHeaderCellStyle( - rowIndex, - cellIndex, - subColumns, - column, - hasGutter - ), - onClick: ($event) => handleHeaderClick($event, column), - onContextmenu: ($event) => - handleHeaderContextMenu($event, column), - onMousedown: ($event) => handleMouseDown($event, column), - onMousemove: ($event) => handleMouseMove($event, column), - onMouseout: handleMouseOut, - }, - [ - h( - 'div', - { - class: [ - 'cell', - column.filteredValue && - column.filteredValue.length > 0 - ? 'highlight' - : '', - column.labelClassName, - ], - }, - [ - column.renderHeader - ? column.renderHeader({ - column, - $index: cellIndex, - store, - _self: $parent, - }) - : column.label, - column.sortable && - h( - 'span', - { - onClick: ($event) => - handleSortClick($event, column), - class: 'caret-wrapper', - }, - [ - h('i', { - onClick: ($event) => - handleSortClick( - $event, - column, - 'ascending' - ), - class: 'sort-caret ascending', - }), - h('i', { - onClick: ($event) => - handleSortClick( - $event, - column, - 'descending' - ), - class: 'sort-caret descending', - }), - ] - ), - column.filterable && - h(FilterPanel, { - store: $parent.store, - placement: - column.filterPlacement || 'bottom-start', + subColumns.map((column, cellIndex) => { + if (column.rowSpan > rowSpan) { + rowSpan = column.rowSpan + } + return h( + 'th', + { + class: getHeaderCellClass( + rowIndex, + cellIndex, + subColumns, + column + ), + colspan: column.colSpan, + key: `${column.id}-thead`, + rowSpan: column.rowSpan, + style: getHeaderCellStyle( + rowIndex, + cellIndex, + subColumns, + column + ), + onClick: ($event) => handleHeaderClick($event, column), + onContextmenu: ($event) => + handleHeaderContextMenu($event, column), + onMousedown: ($event) => handleMouseDown($event, column), + onMousemove: ($event) => handleMouseMove($event, column), + onMouseout: handleMouseOut, + }, + [ + h( + 'div', + { + class: [ + 'cell', + column.filteredValue && + column.filteredValue.length > 0 + ? 'highlight' + : '', + column.labelClassName, + ], + }, + [ + column.renderHeader + ? column.renderHeader({ column, - upDataColumn: (key, value) => { - column[key] = value - }, - }), - ] - ), - ] - ) - }) - .concat( - hasGutter && rowIndex === 0 - ? [ - h( - 'th', - { - class: 'el-table__fixed-right-patch el-table__cell', - key: `el-table--scrollbar`, - rowSpan, - style: { - width: `${gutterWidth}px`, + $index: cellIndex, + store, + _self: $parent, + }) + : column.label, + column.sortable && + h( + 'span', + { + onClick: ($event) => + handleSortClick($event, column), + class: 'caret-wrapper', }, - }, - [] - ), + [ + h('i', { + onClick: ($event) => + handleSortClick($event, column, 'ascending'), + class: 'sort-caret ascending', + }), + h('i', { + onClick: ($event) => + handleSortClick($event, column, 'descending'), + class: 'sort-caret descending', + }), + ] + ), + column.filterable && + h(FilterPanel, { + store: $parent.store, + placement: column.filterPlacement || 'bottom-start', + column, + upDataColumn: (key, value) => { + column[key] = value + }, + }), ] - : [] + ), + ] ) + }) ) ) ), diff --git a/packages/components/table/src/table-header/style.helper.ts b/packages/components/table/src/table-header/style.helper.ts index e2a3fc0fc1..b37cf952c0 100644 --- a/packages/components/table/src/table-header/style.helper.ts +++ b/packages/components/table/src/table-header/style.helper.ts @@ -3,7 +3,6 @@ import { getFixedColumnsClass, getFixedColumnOffset, ensurePosition, - ensureRightFixedStyle, } from '../util' import type { TableColumnCtx } from '../table-column/defaults' import type { Table } from '../table/defaults' @@ -37,8 +36,7 @@ function useStyle(props: TableHeaderProps) { rowIndex: number, columnIndex: number, row: T, - column: TableColumnCtx, - hasGutter: boolean + column: TableColumnCtx ) => { let headerCellStyles = parent.props.headerCellStyle ?? {} if (typeof headerCellStyles === 'function') { @@ -55,7 +53,6 @@ function useStyle(props: TableHeaderProps) { props.store, row as unknown as TableColumnCtx[] ) - ensureRightFixedStyle(fixedStyle, hasGutter) ensurePosition(fixedStyle, 'left') ensurePosition(fixedStyle, 'right') return Object.assign({}, headerCellStyles, fixedStyle) diff --git a/packages/components/table/src/table-layout.ts b/packages/components/table/src/table-layout.ts index e364c2b491..90d108c852 100644 --- a/packages/components/table/src/table-layout.ts +++ b/packages/components/table/src/table-layout.ts @@ -1,7 +1,6 @@ import { nextTick, ref, isRef } from 'vue' import { hasOwn } from '@vue/shared' import { isClient } from '@vueuse/core' -import scrollbarWidth from '@element-plus/utils/scrollbar-width' import { parseHeight } from './util' import type { Ref } from 'vue' @@ -53,7 +52,7 @@ class TableLayout { this.bodyHeight = ref(null) this.bodyScrollHeight = ref(0) this.fixedBodyHeight = ref(null) - this.gutterWidth = scrollbarWidth() + this.gutterWidth = 0 for (const name in options) { if (hasOwn(options, name)) { if (isRef(this[name])) { diff --git a/packages/components/table/src/table.vue b/packages/components/table/src/table.vue index c3f07f1106..a9867f4599 100644 --- a/packages/components/table/src/table.vue +++ b/packages/components/table/src/table.vue @@ -15,6 +15,7 @@ 'el-table--enable-row-transition': (store.states.data.value || []).length !== 0 && (store.states.data.value || []).length < 100, + 'has-footer': showSummary, }, tableSize ? `el-table--${tableSize}` : '', className, @@ -43,42 +44,39 @@ />
- -
- - {{ computedEmptyText }} - -
-
- -
+ + +
+ + {{ computedEmptyText }} + +
+
+ +
+
-