wip: Table component developing
This commit is contained in:
@@ -1,3 +1,7 @@
|
||||
import Table from './src/Table.vue'
|
||||
|
||||
export interface TableExpose {
|
||||
setProps: (props: Recordable) => void
|
||||
}
|
||||
|
||||
export { Table }
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
<script lang="tsx">
|
||||
import { ElTable, ElTableColumn } from 'element-plus'
|
||||
import { defineComponent, PropType, ref, computed, unref } from 'vue'
|
||||
import { ElTable, ElTableColumn, ElPagination } 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 } from './types'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Table',
|
||||
props: {
|
||||
pageSize: propTypes.number.def(10),
|
||||
currentPage: propTypes.number.def(1),
|
||||
// 是否多选
|
||||
selection: propTypes.bool.def(true),
|
||||
// 是否所有的超出隐藏,优先级低于schema中的showOverflowTooltip,
|
||||
@@ -18,33 +21,105 @@ export default defineComponent({
|
||||
default: () => []
|
||||
},
|
||||
// 是否展示分页
|
||||
// pagination: {
|
||||
// type: [Boolean, Object] as PropType<boolean | IObj>,
|
||||
// default: false
|
||||
// },
|
||||
pagination: {
|
||||
type: Object as PropType<Pagination>,
|
||||
default: (): Pagination | undefined => undefined
|
||||
},
|
||||
// 仅对 type=selection 的列有效,类型为 Boolean,为 true 则会在数据更新之后保留之前选中的数据(需指定 row-key)
|
||||
reserveSelection: propTypes.bool.def(false),
|
||||
// 加载状态
|
||||
loading: propTypes.bool.def(false),
|
||||
// 是否叠加索引
|
||||
reserveIndex: propTypes.bool.def(true),
|
||||
reserveIndex: propTypes.bool.def(false),
|
||||
// 对齐方式
|
||||
align: propTypes.string
|
||||
.validate((v: string) => ['left', 'center', 'right'].includes(v))
|
||||
.def('left'),
|
||||
// 表头对齐方式
|
||||
headerAlign: propTypes.string
|
||||
.validate((v: string) => ['left', 'center', 'right'].includes(v))
|
||||
.def('left'),
|
||||
// 表头对齐方式
|
||||
data: {
|
||||
type: Array as PropType<Recordable[]>,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
setup(props, { attrs, slots }) {
|
||||
const tableRef = ref<ComponentRef<typeof ElTable>>()
|
||||
emits: ['update:pageSize', 'update:currentPage', 'register'],
|
||||
setup(props, { attrs, slots, emit, expose }) {
|
||||
const elTableRef = ref<ComponentRef<typeof ElTable>>()
|
||||
|
||||
const getProps = computed(() => props)
|
||||
// 注册
|
||||
onMounted(() => {
|
||||
emit('register', unref(elTableRef)?.$parent, unref(elTableRef))
|
||||
})
|
||||
|
||||
const pageSizeRef = ref(props.pageSize)
|
||||
|
||||
const currentPageRef = ref(props.currentPage)
|
||||
|
||||
// useTable传入的props
|
||||
const outsideProps = ref<TableProps>({})
|
||||
|
||||
const mergeProps = ref<TableProps>({})
|
||||
|
||||
const getProps = computed(() => {
|
||||
const propsObj = { ...props }
|
||||
Object.assign(propsObj, unref(mergeProps))
|
||||
return propsObj
|
||||
})
|
||||
|
||||
const setProps = (props: TableProps = {}) => {
|
||||
mergeProps.value = Object.assign(unref(mergeProps), props)
|
||||
outsideProps.value = props
|
||||
}
|
||||
|
||||
expose({
|
||||
setProps
|
||||
})
|
||||
|
||||
const pagination = computed(() => {
|
||||
return Object.assign(
|
||||
{
|
||||
small: false,
|
||||
background: false,
|
||||
pagerCount: 7,
|
||||
layout: 'sizes, prev, pager, next, jumper, ->, total',
|
||||
pageSizes: [10, 20, 30, 40, 50, 100],
|
||||
disabled: false,
|
||||
hideOnSinglePage: false,
|
||||
total: 10
|
||||
},
|
||||
unref(getProps).pagination
|
||||
)
|
||||
})
|
||||
|
||||
watch(
|
||||
() => unref(getProps).pageSize,
|
||||
(val: number) => {
|
||||
pageSizeRef.value = val
|
||||
}
|
||||
)
|
||||
|
||||
watch(
|
||||
() => unref(getProps).currentPage,
|
||||
(val: number) => {
|
||||
currentPageRef.value = val
|
||||
}
|
||||
)
|
||||
|
||||
watch(
|
||||
() => pageSizeRef.value,
|
||||
(val: number) => {
|
||||
emit('update:pageSize', val)
|
||||
}
|
||||
)
|
||||
|
||||
watch(
|
||||
() => currentPageRef.value,
|
||||
(val: number) => {
|
||||
emit('update:currentPage', val)
|
||||
}
|
||||
)
|
||||
|
||||
const getBindValue = computed(() => {
|
||||
const bindValue: Recordable = { ...attrs, ...props }
|
||||
@@ -54,25 +129,37 @@ export default defineComponent({
|
||||
})
|
||||
|
||||
const renderTableSelection = () => {
|
||||
return (
|
||||
// 渲染多选
|
||||
return unref(getProps).selection ? (
|
||||
<ElTableColumn
|
||||
type="selection"
|
||||
reserveSelection={props.reserveSelection}
|
||||
reserveSelection={unref(getProps).reserveSelection}
|
||||
align={unref(getProps).align}
|
||||
headerAlign={unref(getProps).headerAlign}
|
||||
width="50"
|
||||
></ElTableColumn>
|
||||
)
|
||||
) : undefined
|
||||
}
|
||||
|
||||
const rnderTableColumn = (columns: TableColumn[]) => {
|
||||
return (props.selection ? [renderTableSelection()] : []).concat(
|
||||
return [renderTableSelection()].concat(
|
||||
columns.map((v) => {
|
||||
// 自定生成序号
|
||||
if (v.type === 'index') {
|
||||
return (
|
||||
<ElTableColumn
|
||||
type="index"
|
||||
index={v.index ? v.index : setIndex()}
|
||||
index={
|
||||
v.index
|
||||
? v.index
|
||||
: (index) =>
|
||||
setIndex(
|
||||
unref(getProps).reserveIndex,
|
||||
index,
|
||||
unref(getProps).pageSize,
|
||||
unref(getProps).currentPage
|
||||
)
|
||||
}
|
||||
align={v.align || unref(getProps).align}
|
||||
headerAlign={v.headerAlign || unref(getProps).headerAlign}
|
||||
label={v.label}
|
||||
@@ -91,7 +178,9 @@ export default defineComponent({
|
||||
{{
|
||||
default: (data: TableSlotDefault) =>
|
||||
// @ts-ignore
|
||||
getSlot(slots, v.field, data) || v?.formatter?.() || data.row[v.field],
|
||||
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`)
|
||||
}}
|
||||
@@ -106,17 +195,25 @@ export default defineComponent({
|
||||
<>
|
||||
<ElTable
|
||||
// @ts-ignore
|
||||
ref={tableRef}
|
||||
ref={elTableRef}
|
||||
data={unref(getProps).data}
|
||||
{...getBindValue}
|
||||
v-loading={unref(getProps).loading}
|
||||
>
|
||||
{{
|
||||
default: () => rnderTableColumn(props.columns),
|
||||
default: () => rnderTableColumn(unref(getProps).columns),
|
||||
// @ts-ignore
|
||||
append: () => getSlot(slots, 'append')
|
||||
}}
|
||||
</ElTable>
|
||||
{unref(getProps).pagination ? (
|
||||
<ElPagination
|
||||
v-model:pageSize={pageSizeRef.value}
|
||||
v-model:currentPage={currentPageRef.value}
|
||||
class="mt-10px"
|
||||
{...unref(pagination)}
|
||||
></ElPagination>
|
||||
) : undefined}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
export const setIndex = () => {
|
||||
return 1
|
||||
export const setIndex = (reserveIndex: boolean, index: number, size: number, current: number) => {
|
||||
const newIndex = index + 1
|
||||
if (reserveIndex) {
|
||||
return size * (current - 1) + newIndex
|
||||
} else {
|
||||
return newIndex
|
||||
}
|
||||
}
|
||||
|
||||
23
src/components/Table/src/types.ts
Normal file
23
src/components/Table/src/types.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
export type TableProps = {
|
||||
pageSize?: number
|
||||
currentPage?: number
|
||||
// 是否多选
|
||||
selection?: boolean
|
||||
// 是否所有的超出隐藏,优先级低于schema中的showOverflowTooltip,
|
||||
showOverflowTooltip?: boolean
|
||||
// 表头
|
||||
columns?: TableColumn[]
|
||||
// 是否展示分页
|
||||
pagination?: Pagination | undefined
|
||||
// 仅对 type=selection 的列有效,类型为 Boolean,为 true 则会在数据更新之后保留之前选中的数据(需指定 row-key)
|
||||
reserveSelection?: boolean
|
||||
// 加载状态
|
||||
loading?: boolean
|
||||
// 是否叠加索引
|
||||
reserveIndex?: boolean
|
||||
// 对齐方式
|
||||
align?: 'left' | 'center' | 'right'
|
||||
// 表头对齐方式
|
||||
headerAlign?: 'left' | 'center' | 'right'
|
||||
data?: Recordable
|
||||
} & Recordable
|
||||
Reference in New Issue
Block a user