perf(components): [el-table] optimize the performance of expand rows (#6480)

* perf(components): [el-table] optimize the performance of expand rows

* chore: revert comments

* chore: remove useless code

* chore: rename

* Update packages/components/table/src/table-body/render-helper.ts

Co-authored-by: JeremyWuuuuu <15975785+JeremyWuuuuu@users.noreply.github.com>

Co-authored-by: JeremyWuuuuu <15975785+JeremyWuuuuu@users.noreply.github.com>
This commit is contained in:
msidolphin 2022-03-10 16:45:08 +08:00 committed by GitHub
parent 76735a6560
commit 254eacd7da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 65 additions and 44 deletions

View File

@ -112,10 +112,18 @@ export const cellForced = {
renderHeader<T>({ column }: { column: TableColumnCtx<T> }) {
return column.label || ''
},
renderCell<T>({ row, store }: { row: T; store: Store<T> }) {
renderCell<T>({
row,
store,
expanded,
}: {
row: T
store: Store<T>
expanded: boolean
}) {
const { ns } = store
const classes = [ns.e('expand-icon')]
if (store.states.expandRows.value.includes(row)) {
if (expanded) {
classes.push(ns.em('expand-icon', 'expanded'))
}
const callback = function (e: Event) {

View File

@ -34,7 +34,6 @@ function useExpand<T>(watcherData: WatcherPropsData<T>) {
const changed = toggleRowStatus(expandRows.value, row, expanded)
if (changed) {
instance.emit('expand-change', row, expandRows.value.slice())
instance.store.scheduleLayout()
}
}

View File

@ -39,7 +39,12 @@ function useRender<T>(props: Partial<TableBodyProps<T>>) {
}
return index
}
const rowRender = (row: T, $index: number, treeRowData?: TreeNode) => {
const rowRender = (
row: T,
$index: number,
treeRowData?: TreeNode,
expanded = false
) => {
const { tooltipEffect, store } = props
const { indent, columns } = store.states
const rowClasses = getRowClass(row, $index)
@ -82,6 +87,7 @@ function useRender<T>(props: Partial<TableBodyProps<T>>) {
column: columnData,
row,
$index,
expanded,
}
if (cellIndex === firstDefaultColumnIndex.value && treeRowData) {
data.treeNode = {
@ -122,44 +128,51 @@ function useRender<T>(props: Partial<TableBodyProps<T>>) {
const cellChildren = (cellIndex, column, data) => {
return column.renderCell(data)
}
const wrappedRowRender = (row: T, $index: number) => {
const store = props.store
const { isRowExpanded, assertRowKey } = store
const { treeData, lazyTreeNodeMap, childrenColumnName, rowKey } =
store.states
const hasExpandColumn = store.states.columns.value.some(
({ type }) => type === 'expand'
)
if (hasExpandColumn && isRowExpanded(row)) {
const columns = store.states.columns.value
const hasExpandColumn = columns.some(({ type }) => type === 'expand')
if (hasExpandColumn) {
const expanded = isRowExpanded(row)
const tr = rowRender(row, $index, undefined, expanded)
const renderExpanded = parent.renderExpanded
const tr = rowRender(row, $index, undefined)
if (!renderExpanded) {
console.error('[Element Error]renderExpanded is required.')
return tr
if (expanded) {
if (!renderExpanded) {
console.error('[Element Error]renderExpanded is required.')
return tr
}
// 使用二维数组,避免修改 $index
// Use a matrix to avoid modifying $index
return [
[
tr,
h(
'tr',
{
key: `expanded-row__${tr.key as string}`,
},
[
h(
'td',
{
colspan: columns.length,
class: 'el-table__cell el-table__expanded-cell',
},
[renderExpanded({ row, $index, store, expanded })]
),
]
),
],
]
} else {
// 使用二维数组,避免修改 $index
// Use a two dimensional array avoid modifying $index
return [[tr]]
}
// 使用二维数组,避免修改 $index
// Use a two dimensional array avoid modifying $index
return [
[
tr,
h(
'tr',
{
key: `expanded-row__${tr.key as string}`,
},
[
h(
'td',
{
colspan: store.states.columns.value.length,
class: 'el-table__cell el-table__expanded-cell',
},
[renderExpanded({ row, $index, store })]
),
]
),
],
]
} else if (Object.keys(treeData.value).length) {
assertRowKey()
// TreeTable 时rowKey 必须由用户设定,不使用 getKeyOfRow 计算

View File

@ -47,11 +47,6 @@ function useStyles<T>(props: Partial<TableBodyProps<T>>) {
})
)
}
if (props.store.states.expandRows.value.includes(row)) {
classes.push('expanded')
}
return classes
}

View File

@ -37,9 +37,14 @@ type HoverState<T> = Nullable<{
row: T
}>
type RIS<T> = { row: T; $index: number; store: Store<T> }
type RIS<T> = { row: T; $index: number; store: Store<T>; expanded: boolean }
type RenderExpanded<T> = ({ row, $index, store }: RIS<T>) => VNode
type RenderExpanded<T> = ({
row,
$index,
store,
expanded: boolean,
}: RIS<T>) => VNode
type SummaryMethod<T> = (data: {
columns: TableColumnCtx<T>
@ -161,6 +166,7 @@ interface RenderRowData<T> {
row: T
$index: number
treeNode?: TreeNode
expanded: boolean
}
export default {

View File

@ -148,7 +148,7 @@ function useStyle<T>(
const { tableWrapper } = table.refs
setScrollClassByEl(tableWrapper, className)
}
const existsScrollClass = (className: string) => {
const hasScrollClass = (className: string) => {
const { tableWrapper } = table.refs
if (tableWrapper && tableWrapper.classList.contains(className)) {
return true
@ -159,7 +159,7 @@ function useStyle<T>(
if (!table.refs.scrollWrapper) return
if (!layout.scrollX.value) {
const scrollingNoneClass = 'is-scrolling-none'
if (!existsScrollClass(scrollingNoneClass)) {
if (!hasScrollClass(scrollingNoneClass)) {
setScrollClass(scrollingNoneClass)
}
return