diff --git a/src/components/Table/index.ts b/src/components/Table/index.ts index 644a160..af647af 100644 --- a/src/components/Table/index.ts +++ b/src/components/Table/index.ts @@ -2,6 +2,7 @@ import Table from './src/Table.vue' export interface TableExpose { setProps: (props: Recordable) => void + setColumn: (columnProps: TableSetPropsType[]) => void } export { Table } diff --git a/src/components/Table/src/Table.vue b/src/components/Table/src/Table.vue index b9cea98..2fedbc6 100644 --- a/src/components/Table/src/Table.vue +++ b/src/components/Table/src/Table.vue @@ -5,6 +5,7 @@ import { propTypes } from '@/utils/propTypes' import { setIndex } from './helper' import { getSlot } from '@/utils/tsxHelper' import type { TableProps } from './types' +import { set } from 'lodash-es' export default defineComponent({ name: 'Table', @@ -20,6 +21,8 @@ export default defineComponent({ type: Array as PropType, default: () => [] }, + // 展开行 + expand: propTypes.bool.def(false), // 是否展示分页 pagination: { type: Object as PropType, @@ -73,8 +76,22 @@ export default defineComponent({ outsideProps.value = props } + const setColumn = (columnProps: TableSetPropsType[], columnsChildren?: TableColumn[]) => { + const { columns } = unref(getProps) + for (const v of columnsChildren || columns) { + for (const item of columnProps) { + if (v.field === item.field) { + set(v, item.path, item.value) + } else if (v.children?.length) { + setColumn(columnProps, v.children) + } + } + } + } + expose({ - setProps + setProps, + setColumn }) const pagination = computed(() => { @@ -129,21 +146,73 @@ export default defineComponent({ }) const renderTableSelection = () => { + const { selection, reserveSelection, align, headerAlign } = unref(getProps) // 渲染多选 - return unref(getProps).selection ? ( + return selection ? ( ) : undefined } - const rnderTableColumn = (columns: TableColumn[]) => { - return [renderTableSelection()].concat( - columns.map((v) => { + const renderTableExpand = () => { + const { align, headerAlign } = unref(getProps) + // 渲染展开行 + return unref(getProps).expand ? ( + + {{ + // @ts-ignore + default: (data: TableSlotDefault) => getSlot(slots, 'expand', data) + }} + + ) : undefined + } + + const rnderTreeTableColumn = (columnsChildren: TableColumn[]) => { + const { align, headerAlign, showOverflowTooltip } = unref(getProps) + return columnsChildren.map((v) => { + const props = { ...v } + if (props.children) delete props.children + return ( + + {{ + default: (data: TableSlotDefault) => + v.children && v.children.length + ? rnderTableColumn(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`) + }} + + ) + }) + } + + const rnderTableColumn = (columnsChildren?: TableColumn[]) => { + const { + columns, + reserveIndex, + pageSize, + currentPage, + align, + headerAlign, + showOverflowTooltip + } = unref(getProps) + return [...[renderTableExpand()], ...[renderTableSelection()]].concat( + (columnsChildren || columns).map((v) => { // 自定生成序号 if (v.type === 'index') { return ( @@ -152,35 +221,33 @@ export default defineComponent({ index={ v.index ? v.index - : (index) => - setIndex( - unref(getProps).reserveIndex, - index, - unref(getProps).pageSize, - unref(getProps).currentPage - ) + : (index) => setIndex(reserveIndex, index, pageSize, currentPage) } - align={v.align || unref(getProps).align} - headerAlign={v.headerAlign || unref(getProps).headerAlign} + align={v.align || align} + headerAlign={v.headerAlign || headerAlign} label={v.label} width="100px" > ) } else { + const props = { ...v } + if (props.children) delete props.children return ( {{ default: (data: TableSlotDefault) => - // @ts-ignore - getSlot(slots, v.field, data) || - v?.formatter?.(data.row, data.column, data.row[v.field], data.$index) || - data.row[v.field], + v.children && v.children.length + ? rnderTreeTableColumn(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`) }} @@ -201,7 +268,7 @@ export default defineComponent({ v-loading={unref(getProps).loading} > {{ - default: () => rnderTableColumn(unref(getProps).columns), + default: () => rnderTableColumn(), // @ts-ignore append: () => getSlot(slots, 'append') }} diff --git a/src/components/Table/src/types.ts b/src/components/Table/src/types.ts index d35e692..58ecd83 100644 --- a/src/components/Table/src/types.ts +++ b/src/components/Table/src/types.ts @@ -20,4 +20,5 @@ export type TableProps = { // 表头对齐方式 headerAlign?: 'left' | 'center' | 'right' data?: Recordable + expand?: boolean } & Recordable diff --git a/src/hooks/web/useTable.ts b/src/hooks/web/useTable.ts index 442f184..a2c8cde 100644 --- a/src/hooks/web/useTable.ts +++ b/src/hooks/web/useTable.ts @@ -12,6 +12,7 @@ interface UseTableConfig { list: string total?: string } + props?: TableProps } interface TableObject { @@ -88,7 +89,11 @@ export const useTable = ( return table } - const methods = { + const methods: { + setProps: (props: Recordable) => void + getList: () => Promise + setColumn: (columnProps: TableSetPropsType[]) => void + } = { getList: async () => { tableObject.loading = true const res = await config @@ -105,11 +110,18 @@ export const useTable = ( setProps: async (props: TableProps = {}) => { const table = await getTable() table?.setProps(props) + }, + setColumn: async (columnProps: TableSetPropsType[]) => { + const table = await getTable() + table?.setColumn(columnProps) } } + config?.props && methods.setProps(config.props) + return { register, + elTableRef, tableObject, methods } diff --git a/src/locales/en.ts b/src/locales/en.ts index 60213f0..03d8072 100644 --- a/src/locales/en.ts +++ b/src/locales/en.ts @@ -324,9 +324,11 @@ export default { pagination: 'pagination', reserveIndex: 'Reserve index', restoreIndex: 'Restore index', - showSelections: 'show selections', - hiddenSelections: 'restore selections', - showExpandedRows: 'show expanded rows', - hiddenExpandedRows: 'hidden expanded rows' + showSelections: 'Show selections', + hiddenSelections: 'Restore selections', + showExpandedRows: 'Show expanded rows', + hiddenExpandedRows: 'Hidden expanded rows', + changeTitle: 'Change title', + header: 'Header' } } diff --git a/src/locales/zh-CN.ts b/src/locales/zh-CN.ts index 5ac0378..48b04ce 100644 --- a/src/locales/zh-CN.ts +++ b/src/locales/zh-CN.ts @@ -324,6 +324,8 @@ export default { showSelections: '显示多选', hiddenSelections: '隐藏多选', showExpandedRows: '显示展开行', - hiddenExpandedRows: '隐藏展开行' + hiddenExpandedRows: '隐藏展开行', + changeTitle: '修改标题', + header: '头部' } } diff --git a/src/router/index.ts b/src/router/index.ts index a8c8466..74ac7d8 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -155,6 +155,14 @@ export const asyncRouterMap: AppRouteRecordRaw[] = [ meta: { title: 'UseTable' } + }, + { + path: 'ref-table', + component: () => import('@/views/Components/Table/RefTable.vue'), + name: 'RefTable', + meta: { + title: 'RefTable' + } } ] }, diff --git a/src/views/Components/Table/RefTable.vue b/src/views/Components/Table/RefTable.vue new file mode 100644 index 0000000..05a69b7 --- /dev/null +++ b/src/views/Components/Table/RefTable.vue @@ -0,0 +1,181 @@ + + + diff --git a/src/views/Components/Table/UseTableDemo.vue b/src/views/Components/Table/UseTableDemo.vue index fb2bac7..26a5d11 100644 --- a/src/views/Components/Table/UseTableDemo.vue +++ b/src/views/Components/Table/UseTableDemo.vue @@ -4,7 +4,7 @@ import { useI18n } from '@/hooks/web/useI18n' import { Table } from '@/components/Table' import { getTableListApi } from '@/api/table' import { TableData } from '@/api/table/types' -import { ref, h } from 'vue' +import { ref, h, reactive, unref } from 'vue' import { ElTag, ElButton } from 'element-plus' import { useTable } from '@/hooks/web/useTable' @@ -28,51 +28,57 @@ getList() const { t } = useI18n() -const columns: TableColumn[] = [ +const columns = reactive([ { field: 'index', label: t('tableDemo.index'), type: 'index' }, { - field: 'title', - label: t('tableDemo.title') - }, - { - field: 'author', - label: t('tableDemo.author') - }, - { - field: 'display_time', - label: t('tableDemo.displayTime') - }, - { - field: 'importance', - label: t('tableDemo.importance'), - formatter: (_: Recordable, __: TableColumn, cellValue: number) => { - return h( - ElTag, - { - type: cellValue === 1 ? 'success' : cellValue === 2 ? 'warning' : 'danger' - }, - () => - cellValue === 1 - ? t('tableDemo.important') - : cellValue === 2 - ? t('tableDemo.good') - : t('tableDemo.commonly') - ) - } - }, - { - field: 'pageviews', - label: t('tableDemo.pageviews') + field: 'content', + label: t('tableDemo.header'), + children: [ + { + field: 'title', + label: t('tableDemo.title') + }, + { + field: 'author', + label: t('tableDemo.author') + }, + { + field: 'display_time', + label: t('tableDemo.displayTime') + }, + { + field: 'importance', + label: t('tableDemo.importance'), + formatter: (_: Recordable, __: TableColumn, cellValue: number) => { + return h( + ElTag, + { + type: cellValue === 1 ? 'success' : cellValue === 2 ? 'warning' : 'danger' + }, + () => + cellValue === 1 + ? t('tableDemo.important') + : cellValue === 2 + ? t('tableDemo.good') + : t('tableDemo.commonly') + ) + } + }, + { + field: 'pageviews', + label: t('tableDemo.pageviews') + } + ] }, { field: 'action', label: t('tableDemo.action') } -] +]) const acitonFn = (data: TableSlotDefault) => { console.log(data) @@ -103,6 +109,27 @@ const showSelections = (show: boolean) => { selection: show }) } + +const index = ref(1) + +const changeTitle = () => { + const { setColumn } = methods + setColumn([ + { + field: 'title', + path: 'label', + value: `${t('tableDemo.title')}${unref(index)}` + } + ]) + index.value++ +} + +const showExpandedRows = (show: boolean) => { + const { setProps } = methods + setProps({ + expand: show + }) +} + + diff --git a/types/componentType/table.d.ts b/types/componentType/table.d.ts index 4263b98..fe2100c 100644 --- a/types/componentType/table.d.ts +++ b/types/componentType/table.d.ts @@ -1,6 +1,7 @@ declare type TableColumn = { field: string label?: string + children?: TableColumn[] } & Recordable declare type TableSlotDefault = { @@ -27,3 +28,9 @@ declare interface Pagination { disabled?: boolean hideOnSinglePage?: boolean } + +declare interface TableSetPropsType { + field: string + path: string + value: any +}