|
|
|
|
@ -1,11 +1,11 @@
|
|
|
|
|
<script lang="tsx">
|
|
|
|
|
import { ElTable, ElTableColumn, ElPagination } from 'element-plus'
|
|
|
|
|
import { ElTable, ElTableColumn, ElPagination, ComponentSize, ElTooltipProps } from 'element-plus'
|
|
|
|
|
import { defineComponent, PropType, ref, computed, unref, watch, onMounted } from 'vue'
|
|
|
|
|
import { propTypes } from '@/utils/propTypes'
|
|
|
|
|
import { setIndex } from './helper'
|
|
|
|
|
import { getSlot } from '@/utils/tsxHelper'
|
|
|
|
|
import type { TableProps, TableColumn, TableSlotDefault, Pagination, TableSetProps } from './types'
|
|
|
|
|
import type { TableProps, TableColumn, Pagination, TableSetProps } from './types'
|
|
|
|
|
import { set } from 'lodash-es'
|
|
|
|
|
import { CSSProperties } from 'vue'
|
|
|
|
|
|
|
|
|
|
export default defineComponent({
|
|
|
|
|
name: 'Table',
|
|
|
|
|
@ -45,10 +45,137 @@ export default defineComponent({
|
|
|
|
|
data: {
|
|
|
|
|
type: Array as PropType<Recordable[]>,
|
|
|
|
|
default: () => []
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
height: propTypes.oneOfType([Number, String]),
|
|
|
|
|
maxHeight: propTypes.oneOfType([Number, String]),
|
|
|
|
|
stripe: propTypes.bool.def(false),
|
|
|
|
|
border: propTypes.bool.def(false),
|
|
|
|
|
size: {
|
|
|
|
|
type: String as PropType<ComponentSize>,
|
|
|
|
|
validator: (v: ComponentSize) => ['medium', 'small', 'mini'].includes(v)
|
|
|
|
|
},
|
|
|
|
|
fit: propTypes.bool.def(true),
|
|
|
|
|
showHeader: propTypes.bool.def(true),
|
|
|
|
|
highlightCurrentRow: propTypes.bool.def(false),
|
|
|
|
|
currentRowKey: propTypes.oneOfType([Number, String]),
|
|
|
|
|
// row-class-name, 类型为 (row: Recordable, rowIndex: number) => string | string
|
|
|
|
|
rowClassName: {
|
|
|
|
|
type: [Function, String] as PropType<(row: Recordable, rowIndex: number) => string | string>,
|
|
|
|
|
default: ''
|
|
|
|
|
},
|
|
|
|
|
rowStyle: {
|
|
|
|
|
type: [Function, Object] as PropType<
|
|
|
|
|
(row: Recordable, rowIndex: number) => Recordable | CSSProperties
|
|
|
|
|
>,
|
|
|
|
|
default: () => undefined
|
|
|
|
|
},
|
|
|
|
|
cellClassName: {
|
|
|
|
|
type: [Function, String] as PropType<
|
|
|
|
|
(row: Recordable, column: any, rowIndex: number) => string | string
|
|
|
|
|
>,
|
|
|
|
|
default: ''
|
|
|
|
|
},
|
|
|
|
|
cellStyle: {
|
|
|
|
|
type: [Function, Object] as PropType<
|
|
|
|
|
(row: Recordable, column: any, rowIndex: number) => Recordable | CSSProperties
|
|
|
|
|
>,
|
|
|
|
|
default: () => undefined
|
|
|
|
|
},
|
|
|
|
|
headerRowClassName: {
|
|
|
|
|
type: [Function, String] as PropType<(row: Recordable, rowIndex: number) => string | string>,
|
|
|
|
|
default: ''
|
|
|
|
|
},
|
|
|
|
|
headerRowStyle: {
|
|
|
|
|
type: [Function, Object] as PropType<
|
|
|
|
|
(row: Recordable, rowIndex: number) => Recordable | CSSProperties
|
|
|
|
|
>,
|
|
|
|
|
default: () => undefined
|
|
|
|
|
},
|
|
|
|
|
headerCellClassName: {
|
|
|
|
|
type: [Function, String] as PropType<
|
|
|
|
|
(row: Recordable, column: any, rowIndex: number) => string | string
|
|
|
|
|
>,
|
|
|
|
|
default: ''
|
|
|
|
|
},
|
|
|
|
|
headerCellStyle: {
|
|
|
|
|
type: [Function, Object] as PropType<
|
|
|
|
|
(row: Recordable, column: any, rowIndex: number) => Recordable | CSSProperties
|
|
|
|
|
>,
|
|
|
|
|
default: () => undefined
|
|
|
|
|
},
|
|
|
|
|
rowKey: {
|
|
|
|
|
type: [Function, String] as PropType<(row: Recordable) => string | string>,
|
|
|
|
|
default: () => 'id'
|
|
|
|
|
},
|
|
|
|
|
emptyText: propTypes.string.def('No Data'),
|
|
|
|
|
defaultExpandAll: propTypes.bool.def(false),
|
|
|
|
|
expandRowKeys: {
|
|
|
|
|
type: Array as PropType<string[]>,
|
|
|
|
|
default: () => []
|
|
|
|
|
},
|
|
|
|
|
defaultSort: {
|
|
|
|
|
type: Object as PropType<{ prop: string; order: string }>,
|
|
|
|
|
default: () => ({})
|
|
|
|
|
},
|
|
|
|
|
tooltipEffect: {
|
|
|
|
|
type: String as PropType<'dark' | 'light'>,
|
|
|
|
|
default: 'dark'
|
|
|
|
|
},
|
|
|
|
|
tooltipOptions: {
|
|
|
|
|
type: Object as PropType<
|
|
|
|
|
Pick<
|
|
|
|
|
ElTooltipProps,
|
|
|
|
|
| 'effect'
|
|
|
|
|
| 'enterable'
|
|
|
|
|
| 'hideAfter'
|
|
|
|
|
| 'offset'
|
|
|
|
|
| 'placement'
|
|
|
|
|
| 'popperClass'
|
|
|
|
|
| 'popperOptions'
|
|
|
|
|
| 'showAfter'
|
|
|
|
|
| 'showArrow'
|
|
|
|
|
>
|
|
|
|
|
>,
|
|
|
|
|
default: () => ({
|
|
|
|
|
enterable: true,
|
|
|
|
|
placement: 'top',
|
|
|
|
|
showArrow: true,
|
|
|
|
|
hideAfter: 200,
|
|
|
|
|
popperOptions: { strategy: 'fixed' }
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
showSummary: propTypes.bool.def(false),
|
|
|
|
|
sumText: propTypes.string.def('Sum'),
|
|
|
|
|
summaryMethod: {
|
|
|
|
|
type: Function as PropType<(param: { columns: any[]; data: any[] }) => any[]>,
|
|
|
|
|
default: () => undefined
|
|
|
|
|
},
|
|
|
|
|
spanMethod: {
|
|
|
|
|
type: Function as PropType<
|
|
|
|
|
(param: { row: any; column: any; rowIndex: number; columnIndex: number }) => any[]
|
|
|
|
|
>,
|
|
|
|
|
default: () => undefined
|
|
|
|
|
},
|
|
|
|
|
selectOnIndeterminate: propTypes.bool.def(true),
|
|
|
|
|
indent: propTypes.number.def(16),
|
|
|
|
|
lazy: propTypes.bool.def(false),
|
|
|
|
|
load: {
|
|
|
|
|
type: Function as PropType<(row: Recordable, treeNode: any, resolve: Function) => void>,
|
|
|
|
|
default: () => undefined
|
|
|
|
|
},
|
|
|
|
|
treeProps: {
|
|
|
|
|
type: Object as PropType<{ hasChildren: string; children: string; label: string }>,
|
|
|
|
|
default: () => ({ hasChildren: 'hasChildren', children: 'children', label: 'label' })
|
|
|
|
|
},
|
|
|
|
|
tableLayout: {
|
|
|
|
|
type: String as PropType<'auto' | 'fixed'>,
|
|
|
|
|
default: 'fixed'
|
|
|
|
|
},
|
|
|
|
|
scrollbarAlwaysOn: propTypes.bool.def(false),
|
|
|
|
|
flexible: propTypes.bool.def(false)
|
|
|
|
|
},
|
|
|
|
|
emits: ['update:pageSize', 'update:currentPage', 'register'],
|
|
|
|
|
setup(props, { attrs, slots, emit, expose }) {
|
|
|
|
|
setup(props, { attrs, emit, expose }) {
|
|
|
|
|
const elTableRef = ref<ComponentRef<typeof ElTable>>()
|
|
|
|
|
|
|
|
|
|
// 注册
|
|
|
|
|
@ -74,7 +201,7 @@ export default defineComponent({
|
|
|
|
|
|
|
|
|
|
const setProps = (props: TableProps = {}) => {
|
|
|
|
|
mergeProps.value = Object.assign(unref(mergeProps), props)
|
|
|
|
|
outsideProps.value = props
|
|
|
|
|
outsideProps.value = { ...props } as any
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const setColumn = (columnProps: TableSetProps[], columnsChildren?: TableColumn[]) => {
|
|
|
|
|
@ -186,6 +313,22 @@ export default defineComponent({
|
|
|
|
|
return columnsChildren.map((v) => {
|
|
|
|
|
const props = { ...v } as any
|
|
|
|
|
if (props.children) delete props.children
|
|
|
|
|
|
|
|
|
|
const children = v.children
|
|
|
|
|
|
|
|
|
|
const slots = {
|
|
|
|
|
default: (...args: any[]) => {
|
|
|
|
|
if (props?.slots?.default) {
|
|
|
|
|
return slots.default(args)
|
|
|
|
|
} else if (children && children.length) {
|
|
|
|
|
return renderTreeTableColumn(children)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (props?.slots?.header) {
|
|
|
|
|
slots['header'] = (...args: any[]) => props.slots.header(args)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<ElTableColumn
|
|
|
|
|
showOverflowTooltip={showOverflowTooltip}
|
|
|
|
|
@ -194,17 +337,7 @@ export default defineComponent({
|
|
|
|
|
{...props}
|
|
|
|
|
prop={v.field}
|
|
|
|
|
>
|
|
|
|
|
{{
|
|
|
|
|
default: (data: TableSlotDefault) =>
|
|
|
|
|
v.children && v.children.length
|
|
|
|
|
? renderTableColumn(v.children)
|
|
|
|
|
: // @ts-ignore
|
|
|
|
|
getSlot(slots, v.field, data) ||
|
|
|
|
|
v?.formatter?.(data.row, data.column, data.row[v.field], data.$index) ||
|
|
|
|
|
data.row[v.field],
|
|
|
|
|
// @ts-ignore
|
|
|
|
|
header: getSlot(slots, `${v.field}-header`)
|
|
|
|
|
}}
|
|
|
|
|
{slots}
|
|
|
|
|
</ElTableColumn>
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
@ -241,6 +374,22 @@ export default defineComponent({
|
|
|
|
|
} else {
|
|
|
|
|
const props = { ...v } as any
|
|
|
|
|
if (props.children) delete props.children
|
|
|
|
|
|
|
|
|
|
const children = v.children
|
|
|
|
|
|
|
|
|
|
const slots = {
|
|
|
|
|
default: (...args: any[]) => {
|
|
|
|
|
if (props?.slots?.default) {
|
|
|
|
|
return slots.default(args)
|
|
|
|
|
} else if (children && children.length) {
|
|
|
|
|
return renderTreeTableColumn(children)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (props?.slots?.header) {
|
|
|
|
|
slots['header'] = (...args: any[]) => props.slots.header(args)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<ElTableColumn
|
|
|
|
|
showOverflowTooltip={showOverflowTooltip}
|
|
|
|
|
@ -249,17 +398,7 @@ export default defineComponent({
|
|
|
|
|
{...props}
|
|
|
|
|
prop={v.field}
|
|
|
|
|
>
|
|
|
|
|
{{
|
|
|
|
|
default: (data: TableSlotDefault) =>
|
|
|
|
|
v.children && v.children.length
|
|
|
|
|
? renderTreeTableColumn(v.children)
|
|
|
|
|
: // @ts-ignore
|
|
|
|
|
getSlot(slots, v.field, data) ||
|
|
|
|
|
v?.formatter?.(data.row, data.column, data.row[v.field], data.$index) ||
|
|
|
|
|
data.row[v.field],
|
|
|
|
|
// @ts-ignore
|
|
|
|
|
header: () => getSlot(slots, `${v.field}-header`) || v.label
|
|
|
|
|
}}
|
|
|
|
|
{slots}
|
|
|
|
|
</ElTableColumn>
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
@ -270,16 +409,13 @@ export default defineComponent({
|
|
|
|
|
return () => (
|
|
|
|
|
<div v-loading={unref(getProps).loading}>
|
|
|
|
|
<ElTable
|
|
|
|
|
// @ts-ignore
|
|
|
|
|
ref={elTableRef}
|
|
|
|
|
data={unref(getProps).data}
|
|
|
|
|
onSelection-change={selectionChange}
|
|
|
|
|
{...unref(getBindValue)}
|
|
|
|
|
>
|
|
|
|
|
{{
|
|
|
|
|
default: () => renderTableColumn(),
|
|
|
|
|
// @ts-ignore
|
|
|
|
|
append: () => getSlot(slots, 'append')
|
|
|
|
|
default: () => renderTableColumn()
|
|
|
|
|
}}
|
|
|
|
|
</ElTable>
|
|
|
|
|
{unref(getProps).pagination ? (
|
|
|
|
|
|