element-plus
Version:
A Component Library for Vue 3
1 lines • 12.4 kB
Source Map (JSON)
{"version":3,"file":"tree.mjs","names":[],"sources":["../../../../../../../packages/components/table/src/store/tree.ts"],"sourcesContent":["import { computed, getCurrentInstance, ref, unref, watch } from 'vue'\nimport { isArray, isUndefined } from '@element-plus/utils'\nimport { getRowIdentity, walkTreeNode } from '../util'\n\nimport type { WatcherPropsData } from '.'\nimport type { DefaultRow, Table, TableProps, TreeNode } from '../table/defaults'\n\nexport interface TreeData extends TreeNode {\n children?: string[]\n lazy?: boolean\n loaded?: boolean\n}\n\nfunction useTree<T extends DefaultRow>(watcherData: WatcherPropsData<T>) {\n const expandRowKeys = ref<Array<string>>([])\n const treeData = ref<Record<string, TreeData>>({})\n const indent = ref(16)\n const lazy = ref(false)\n const lazyTreeNodeMap = ref<Record<string, T[]>>({})\n const lazyColumnIdentifier = ref('hasChildren')\n const childrenColumnName = ref('children')\n const checkStrictly = ref(false)\n const instance = getCurrentInstance() as Table<T>\n const normalizedData = computed(() => {\n if (!watcherData.rowKey.value) return {}\n const data = watcherData.data.value || []\n return normalize(data)\n })\n const normalizedLazyNode = computed(() => {\n const rowKey = watcherData.rowKey.value\n const keys = Object.keys(lazyTreeNodeMap.value)\n const res: Record<string, { children: string[] }> = {}\n if (!keys.length) return res\n keys.forEach((key) => {\n if (lazyTreeNodeMap.value[key].length) {\n const item: (typeof res)[number] = { children: [] }\n lazyTreeNodeMap.value[key].forEach((row) => {\n const currentRowKey = getRowIdentity(row, rowKey)\n item.children.push(currentRowKey)\n if (row[lazyColumnIdentifier.value] && !res[currentRowKey]) {\n res[currentRowKey] = { children: [] }\n }\n })\n res[key] = item\n }\n })\n return res\n })\n\n const normalize = (data: T[]) => {\n const rowKey = watcherData.rowKey.value\n const res = {} as Record<string, TreeData>\n walkTreeNode(\n data,\n (parent, children, level) => {\n const parentId = getRowIdentity(parent, rowKey)\n if (isArray(children)) {\n res[parentId] = {\n children: children.map((row) => getRowIdentity(row, rowKey)),\n level,\n }\n } else if (lazy.value) {\n // 当 children 不存在且 lazy 为 true,该节点即为懒加载的节点\n res[parentId] = {\n children: [],\n lazy: true,\n level,\n }\n }\n },\n childrenColumnName.value,\n lazyColumnIdentifier.value,\n lazy.value\n )\n return res\n }\n\n const updateTreeData = (\n ifChangeExpandRowKeys = false,\n ifExpandAll?: boolean\n ) => {\n ifExpandAll ||= instance.store?.states.defaultExpandAll.value\n const nested = normalizedData.value\n const normalizedLazyNode_ = normalizedLazyNode.value\n const keys = Object.keys(nested)\n const newTreeData: Record<string, TreeData> = {}\n if (keys.length) {\n const oldTreeData = unref(treeData)\n const rootLazyRowKeys: string[] = []\n const getExpanded = (oldValue: TreeData, key: string) => {\n if (ifChangeExpandRowKeys) {\n if (expandRowKeys.value) {\n return ifExpandAll || expandRowKeys.value.includes(key)\n } else {\n return !!(ifExpandAll || oldValue?.expanded)\n }\n } else {\n const included =\n ifExpandAll ||\n (expandRowKeys.value && expandRowKeys.value.includes(key))\n return !!(oldValue?.expanded || included)\n }\n }\n // 合并 expanded 与 display,确保数据刷新后,状态不变\n keys.forEach((key) => {\n const oldValue = oldTreeData[key]\n const newValue = { ...nested[key] }\n newValue.expanded = getExpanded(oldValue, key)\n if (newValue.lazy) {\n const { loaded = false, loading = false } = oldValue || {}\n newValue.loaded = !!loaded\n newValue.loading = !!loading\n rootLazyRowKeys.push(key)\n }\n newTreeData[key] = newValue\n })\n // 根据懒加载数据更新 treeData\n const lazyKeys = Object.keys(normalizedLazyNode_)\n if (lazy.value && lazyKeys.length && rootLazyRowKeys.length) {\n lazyKeys.forEach((key) => {\n const oldValue = oldTreeData[key]\n const lazyNodeChildren = normalizedLazyNode_[key].children\n if (rootLazyRowKeys.includes(key)) {\n // 懒加载的 root 节点,更新一下原有的数据,原来的 children 一定是空数组\n if (newTreeData[key].children?.length !== 0) {\n throw new Error('[ElTable]children must be an empty array.')\n }\n newTreeData[key].children = lazyNodeChildren\n } else {\n const { loaded = false, loading = false } = oldValue || {}\n newTreeData[key] = {\n lazy: true,\n loaded: !!loaded,\n loading: !!loading,\n expanded: getExpanded(oldValue, key),\n children: lazyNodeChildren,\n level: undefined,\n }\n }\n })\n }\n }\n treeData.value = newTreeData\n instance.store?.updateTableScrollY()\n }\n\n watch(\n () => expandRowKeys.value,\n () => {\n updateTreeData(true)\n },\n { deep: true }\n )\n\n watch(\n () => normalizedData.value,\n () => {\n updateTreeData()\n }\n )\n watch(\n () => normalizedLazyNode.value,\n () => {\n updateTreeData()\n }\n )\n\n const updateTreeExpandKeys = (value: string[]) => {\n expandRowKeys.value = value\n updateTreeData()\n }\n const isUseLazy = (data: TreeData) => {\n return lazy.value && data && 'loaded' in data && !data.loaded\n }\n const toggleTreeExpansion = (row: T, expanded?: boolean) => {\n instance.store.assertRowKey()\n\n const rowKey = watcherData.rowKey.value\n const id = getRowIdentity(row, rowKey)\n const data = id && treeData.value[id]\n if (id && data && 'expanded' in data) {\n const oldExpanded = data.expanded\n expanded = isUndefined(expanded) ? !data.expanded : expanded\n treeData.value[id].expanded = expanded\n if (oldExpanded !== expanded) {\n instance.emit('expand-change', row, expanded)\n }\n expanded && isUseLazy(data) && loadData(row, id, data)\n instance.store.updateTableScrollY()\n }\n }\n\n const loadOrToggle = (row: T) => {\n instance.store.assertRowKey()\n const rowKey = watcherData.rowKey.value\n const id = getRowIdentity(row, rowKey)\n const data = treeData.value[id]\n if (isUseLazy(data)) {\n loadData(row, id, data)\n } else {\n toggleTreeExpansion(row, undefined)\n }\n }\n\n const loadData = (row: T, key: string, treeNode: TreeNode) => {\n const { load } = instance.props as unknown as TableProps<T>\n if (load && !treeData.value[key].loaded) {\n treeData.value[key].loading = true\n load(row, treeNode, (data) => {\n if (!isArray(data)) {\n throw new TypeError('[ElTable] data must be an array')\n }\n treeData.value[key].loading = false\n treeData.value[key].loaded = true\n treeData.value[key].expanded = true\n if (data.length) {\n lazyTreeNodeMap.value = { ...lazyTreeNodeMap.value, [key]: data }\n }\n instance.emit('expand-change', row, true)\n })\n }\n }\n\n const updateKeyChildren = (key: string, data: T[]) => {\n const { lazy, rowKey } = instance.props as unknown as TableProps<T>\n if (!lazy) return\n if (!rowKey) throw new Error('[Table] rowKey is required in updateKeyChild')\n\n if (lazyTreeNodeMap.value[key]) {\n lazyTreeNodeMap.value = { ...lazyTreeNodeMap.value, [key]: data }\n }\n }\n\n return {\n loadData,\n loadOrToggle,\n toggleTreeExpansion,\n updateTreeExpandKeys,\n updateTreeData,\n updateKeyChildren,\n normalize,\n states: {\n expandRowKeys,\n treeData,\n indent,\n lazy,\n lazyTreeNodeMap,\n lazyColumnIdentifier,\n childrenColumnName,\n checkStrictly,\n },\n }\n}\n\nexport default useTree\n"],"mappings":"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"}