feat(components): [virtual-table] Table (#7083)

* feat(components): [virtual-table] Table

- Add composable for column management.

* Update table props
This commit is contained in:
JeremyWuuuuu 2022-04-10 17:50:18 +08:00 committed by GitHub
parent 5849909577
commit 9a05d5cdc2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 182 additions and 35 deletions

View File

@ -1,4 +1,4 @@
import { definePropType } from '@element-plus/utils'
import { definePropType, mutable } from '@element-plus/utils'
import type { CSSProperties } from 'vue'
import type { Column, KeyType } from './types'
@ -31,6 +31,11 @@ export const dataType = {
export const expandColumnKey = String
export const expandKeys = {
type: definePropType<KeyType[]>(Array),
default: () => mutable([]),
} as const
export const requiredNumber = {
type: Number,
required: true,
@ -38,7 +43,7 @@ export const requiredNumber = {
export const rowKey = {
type: definePropType<KeyType>([String, Number, Symbol]),
required: true,
default: 'id',
} as const
/**

View File

@ -20,11 +20,13 @@ export const tableV2HeaderProps = buildProps({
},
headerHeight: {
type: definePropType<number | number[]>([Number, Array]),
required: true,
default: 50,
},
rowWidth: requiredNumberType,
rowHeight: requiredNumberType,
rowHeight: {
type: Number,
default: 50,
},
height: requiredNumberType,
width: requiredNumberType,
} as const)

View File

@ -1,4 +1,16 @@
import { buildProps, definePropType } from '@element-plus/utils'
import {
classType,
columns,
dataType,
expandKeys,
fixedDataType,
requiredNumber,
rowKey,
} from './common'
import { tableV2RowProps } from './row'
import { tableV2HeaderProps } from './header'
import { tableV2GridProps } from './grid'
import type { ExtractPropTypes, StyleValue } from 'vue'
import type {
@ -53,13 +65,17 @@ export type RowClassNameGetter<T> = (
export type ColumnSortHandler<T> = (params: ColumnSortParams<T>) => void
export const tableV2Props = buildProps({
cache: tableV2GridProps.cache,
estimatedRowHeight: tableV2RowProps.estimatedRowHeight,
rowKey,
/**
* extra props deriver
*/
cellProps: {
type: definePropType<any | ExtraCellPropGetter<any>>([Object, Function]),
},
headerClassName: {
// Header attributes
headerClass: {
type: definePropType<string | HeaderClassNameGetter<any>>([
String,
Function,
@ -77,55 +93,54 @@ export const tableV2Props = buildProps({
Function,
]),
},
rowClassName: {
headerHeight: tableV2HeaderProps.headerHeight,
/**
* Footer attributes
*/
footerHeight: {
type: Number,
default: 0,
},
/**
* Row attributes
*/
rowClass: {
type: definePropType<string | RowClassNameGetter<any>>([String, Function]),
},
rowProps: {
type: definePropType<any | ExtractRowPropGetter<any>>([Object, Function]),
},
rowHeight: Number,
/**
* Data models
*/
columns: {
type: definePropType<Column<any>[]>(Array),
required: true,
},
fixedData: {
type: definePropType<any[]>(Array),
},
data: {
type: definePropType<any[]>(Array),
},
columns,
data: dataType,
fixedData: fixedDataType,
/**
* Expanded keys
*/
expandedRowKeys: {
type: definePropType<KeyType[]>(Array),
},
defaultExpandedRowKeys: {
type: definePropType<KeyType[]>(Array),
},
expandColumnKey: tableV2RowProps.expandColumnKey,
expandedRowKeys: expandKeys,
defaultExpandedRowKeys: expandKeys,
/**
* Attributes
*/
classNames: {
type: definePropType<string | string[]>([String, Array]),
},
class: classType,
disabled: Boolean,
footerHeight: {
type: definePropType<number | number[]>([Number, Array]),
},
headerHeight: {
type: definePropType<number | number[]>([Number, Array]),
},
fixed: Boolean,
style: {
type: definePropType<StyleValue>([String, Array, Object]),
},
width: requiredNumber,
height: Number,
maxHeight: Number,
sortBy: {
type: definePropType<{ key: KeyType; order: SortOrder }>(Object),
default: () => ({} as { key: KeyType; order: SortOrder }),
},
/**
@ -134,6 +149,10 @@ export const tableV2Props = buildProps({
onColumnSort: {
type: definePropType<ColumnSortParams<any>>(Function),
},
onExpandedRowsChange: Function,
onRowExpand: Function,
onScroll: tableV2GridProps.onScroll,
rowEventHandlers: tableV2RowProps.rowEventHandlers,
} as const)
export type TableV2Props = ExtractPropTypes<typeof tableV2Props>

View File

@ -1,4 +1,4 @@
import type { RendererElement, RendererNode, StyleValue, VNode } from 'vue'
import type { CSSProperties, RendererElement, RendererNode, VNode } from 'vue'
import type { sortOrders } from './constants'
@ -69,7 +69,7 @@ export type Column<T = any> = {
maxWidth?: number
minWidth?: number
resizable?: boolean
style?: StyleValue
style?: CSSProperties
sortable?: boolean
width: number
/**
@ -83,6 +83,8 @@ export type Column<T = any> = {
[key: string]: any
}
export type Columns<T> = Column<T>[]
export type CustomizedCellsType = VNode<
RendererNode,
RendererElement,

View File

@ -0,0 +1,119 @@
import { computed, unref } from 'vue'
import type { CSSProperties, Ref } from 'vue'
import type { Column, Columns } from './types'
const getColumnStyle = (
column: Column<any>,
fixedColumn: boolean
): CSSProperties => {
const style = {
...(column.style ?? {}),
width: column.width,
}
if (!fixedColumn) {
if (column.maxWidth) style.maxWidth = column.maxWidth
if (column.minWidth) style.maxWidth = column.minWidth
}
return style
}
function useColumns(columns: Ref<Columns<any>>, fixed: Ref<boolean>) {
let mappedColumnsCopy: Columns<any> = []
const mappedColumns = computed(() => {
const _columns = unref(columns)
const ret = _columns.map((column) => {
if (!column.resizable) return column
let { width } = column
if (column.resizable) {
const idx = _columns.findIndex(
(predicated) => column.key === predicated.key
)
if (idx >= 0 && _columns[idx].width === column.width) {
width = mappedColumnsCopy[idx].width
}
}
return {
...column,
width,
}
})
mappedColumnsCopy = ret
return ret
})
const visibleColumns = computed(() => {
return unref(mappedColumns).filter((column) => !column.hidden)
})
const fixedColumnsOnLeft = computed(() =>
unref(visibleColumns).filter(
(column) => column.fixed === 'left' || column.fixed === true
)
)
const fixedColumnOnRight = computed(() =>
unref(visibleColumns).filter((column) => column.fixed === 'right')
)
const normalColumns = computed(() =>
unref(visibleColumns).filter((column) => !column.fixed)
)
const mainColumns = computed(() => {
const ret: Columns<any> = []
unref(fixedColumnsOnLeft).forEach((column) => {
ret.push({
...column,
isPlaceholder: true,
})
})
unref(normalColumns).forEach((column) => {
ret.push(column)
})
unref(fixedColumnOnRight).forEach((column) => {
ret.push({
...column,
isPlaceholder: true,
})
})
return ret
})
const columnsStyle = computed(() => {
const columns = unref(mappedColumns)
return columns.reduce<Record<Column<any>['key'], CSSProperties>>(
(style, column) => {
style[column.key] = getColumnStyle(column, unref(fixed))
return style
},
{}
)
})
return {
columns: mappedColumns,
columnsStyle,
fixedColumnsOnLeft,
fixedColumnOnRight,
mainColumns,
normalColumns,
visibleColumns,
}
}
function useTable() {
// to be filled
}
export { useColumns, useTable }