Ben Lin
2024-06-18 ebbd788fbb2c0b45d4473798efc57eec8ba74a25
src/components/Table/src/hooks/useTableExpand.ts
@@ -1,14 +1,16 @@
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;
@@ -20,46 +22,111 @@
  });
  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,
  };
}