| | |
| | | import type { ComputedRef, Ref } from 'vue'; |
| | | import type { BasicTableProps } from '../types/table'; |
| | | import { computed, unref, ref, toRaw } from 'vue'; |
| | | import { computed, unref, ref, toRaw, nextTick } from 'vue'; |
| | | import { ROW_KEY } from '../const'; |
| | | import { parseRowKeyValue } from '../helper'; |
| | | import type { Key } from 'ant-design-vue/lib/table/interface'; |
| | | |
| | | export function useTableExpand( |
| | | propsRef: ComputedRef<BasicTableProps>, |
| | | tableData: Ref<Recordable[]>, |
| | | emit: EmitType, |
| | | ) { |
| | | const expandedRowKeys = ref<string[]>([]); |
| | | const expandedRowKeys = ref<Key[]>([]); |
| | | |
| | | const getAutoCreateKey = computed(() => { |
| | | return unref(propsRef).autoCreateKey && !unref(propsRef).rowKey; |
| | |
| | | }); |
| | | |
| | | const getExpandOption = computed(() => { |
| | | const { isTreeTable } = unref(propsRef); |
| | | if (!isTreeTable) return {}; |
| | | const { isTreeTable, expandRowByClick } = unref(propsRef); |
| | | if (!isTreeTable && !expandRowByClick) return {}; |
| | | |
| | | return { |
| | | expandedRowKeys: unref(expandedRowKeys), |
| | | onExpandedRowsChange: (keys: string[]) => { |
| | | expandedRowKeys.value = keys; |
| | | emit('expanded-rows-change', keys); |
| | | onExpandedRowsChange: (keyValues: string[]) => { |
| | | expandedRowKeys.value = keyValues; |
| | | emit('expanded-rows-change', keyValues); |
| | | }, |
| | | }; |
| | | }); |
| | | |
| | | function expandAll() { |
| | | const keys = getAllKeys(); |
| | | expandedRowKeys.value = keys; |
| | | } |
| | | |
| | | function expandRows(keys: string[]) { |
| | | // use row ID expands the specified table row |
| | | const { isTreeTable } = unref(propsRef); |
| | | if (!isTreeTable) return; |
| | | expandedRowKeys.value = [...expandedRowKeys.value, ...keys]; |
| | | } |
| | | |
| | | function getAllKeys(data?: Recordable[]) { |
| | | const keys: string[] = []; |
| | | const { childrenColumnName } = unref(propsRef); |
| | | toRaw(data || unref(tableData)).forEach((item) => { |
| | | keys.push(item[unref(getRowKey) as string]); |
| | | const children = item[childrenColumnName || 'children']; |
| | | if (children?.length) { |
| | | keys.push(...getAllKeys(children)); |
| | | } |
| | | }); |
| | | return keys; |
| | | const keyValues = getAllKeys(); |
| | | expandedRowKeys.value = keyValues; |
| | | } |
| | | |
| | | function collapseAll() { |
| | | expandedRowKeys.value = []; |
| | | } |
| | | |
| | | return { getExpandOption, expandAll, expandRows, collapseAll }; |
| | | function expandRows(keyValues: Key[]) { |
| | | // use row ID expands the specified table row |
| | | const { isTreeTable, expandRowByClick } = unref(propsRef); |
| | | if (!isTreeTable && !expandRowByClick) return; |
| | | expandedRowKeys.value = [...expandedRowKeys.value, ...keyValues]; |
| | | } |
| | | |
| | | function collapseRows(keyValues: Key[]) { |
| | | // use row ID collapses the specified table row |
| | | const { isTreeTable, expandRowByClick } = unref(propsRef); |
| | | if (!isTreeTable && !expandRowByClick) return; |
| | | expandedRowKeys.value = unref(expandedRowKeys).filter( |
| | | (keyValue) => !keyValues.includes(keyValue), |
| | | ); |
| | | } |
| | | |
| | | function getAllKeys(data?: Recordable[]) { |
| | | const keyValues: Array<number | string> = []; |
| | | const { childrenColumnName } = unref(propsRef); |
| | | toRaw(data || unref(tableData)).forEach((item) => { |
| | | keyValues.push(parseRowKeyValue(unref(getRowKey), item)); |
| | | const children = item[childrenColumnName || 'children']; |
| | | if (children?.length) { |
| | | keyValues.push(...getAllKeys(children)); |
| | | } |
| | | }); |
| | | return keyValues; |
| | | } |
| | | |
| | | // 获取展开路径 keyValues |
| | | function getKeyPaths( |
| | | records: Recordable[], |
| | | childrenColumnName: string, |
| | | keyValue: Key, |
| | | paths: Array<Key>, |
| | | ): boolean { |
| | | if ( |
| | | records.findIndex((record) => parseRowKeyValue(unref(getRowKey), record) === keyValue) > -1 |
| | | ) { |
| | | paths.push(keyValue); |
| | | return true; |
| | | } else { |
| | | for (const record of records) { |
| | | const children = record[childrenColumnName]; |
| | | if (Array.isArray(children) && getKeyPaths(children, childrenColumnName, keyValue, paths)) { |
| | | paths.push(parseRowKeyValue(unref(getRowKey), record)); |
| | | return true; |
| | | } |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | // 手风琴展开 |
| | | function expandRowAccordion(keyValue: Key) { |
| | | const { childrenColumnName } = unref(propsRef); |
| | | const paths: Array<Key> = []; |
| | | getKeyPaths(tableData.value, childrenColumnName || 'children', keyValue, paths); |
| | | expandedRowKeys.value = paths; |
| | | } |
| | | |
| | | // 监听展开事件,用于支持手风琴展开效果 |
| | | function handleTableExpand(expanded: boolean, record: Recordable) { |
| | | // 手风琴开关 |
| | | // isTreeTable 或 expandRowByClick 时支持 |
| | | // 展开操作 |
| | | if ( |
| | | propsRef.value.accordion && |
| | | (propsRef.value.isTreeTable || propsRef.value.expandRowByClick) && |
| | | expanded |
| | | ) { |
| | | nextTick(() => { |
| | | expandRowAccordion(parseRowKeyValue(unref(getRowKey), record)); |
| | | }); |
| | | } |
| | | } |
| | | |
| | | return { |
| | | getExpandOption, |
| | | expandAll, |
| | | collapseAll, |
| | | expandRows, |
| | | collapseRows, |
| | | expandRowAccordion, |
| | | handleTableExpand, |
| | | }; |
| | | } |