{"version":3,"file":"index.cjs","sources":["../src/utils/tree.ts","../src/components/TreeNode.vue","../src/composables/useTreeSelection.ts","../src/composables/useTreeExpand.ts","../src/composables/useTreeFilter.ts","../src/composables/useTreeDrag.ts","../src/composables/useTreeData.ts","../src/components/VirtualTree.vue","../src/index.ts"],"sourcesContent":["import type { TreeNodeData, TreePropsConfig } from '../types'\r\n\r\n/**\r\n * 默认字段映射配置\r\n */\r\nconst DEFAULT_PROPS: Required<TreePropsConfig> = {\r\n  id: 'id',\r\n  children: 'children',\r\n  label: 'label',\r\n  disabled: 'disabled',\r\n  isLeaf: 'isLeaf'\r\n}\r\n\r\n/**\r\n * 获取节点 ID\r\n */\r\nexport function getNodeId(node: TreeNodeData, props: TreePropsConfig = {}): string | number {\r\n  const config = { ...DEFAULT_PROPS, ...props }\r\n  return node[config.id] ?? node.id ?? ''\r\n}\r\n\r\n/**\r\n * 获取节点标签\r\n */\r\nexport function getNodeLabel(node: TreeNodeData, props: TreePropsConfig = {}): string {\r\n  const config = { ...DEFAULT_PROPS, ...props }\r\n  return node[config.label] ?? node.label ?? ''\r\n}\r\n\r\n/**\r\n * 获取子节点\r\n */\r\nexport function getNodeChildren(node: TreeNodeData, props: TreePropsConfig = {}): TreeNodeData[] {\r\n  const config = { ...DEFAULT_PROPS, ...props }\r\n  return node[config.children] ?? node.children ?? []\r\n}\r\n\r\n/**\r\n * 判断节点是否禁用\r\n */\r\nexport function isNodeDisabled(node: TreeNodeData, props: TreePropsConfig = {}): boolean {\r\n  const config = { ...DEFAULT_PROPS, ...props }\r\n  return node[config.disabled] ?? node.disabled ?? false\r\n}\r\n\r\n/**\r\n * 判断是否为叶子节点\r\n */\r\nexport function isLeafNode(node: TreeNodeData, props: TreePropsConfig = {}): boolean {\r\n  const config = { ...DEFAULT_PROPS, ...props }\r\n  const children = getNodeChildren(node, props)\r\n  if (children.length > 0) return false\r\n  if (node[config.isLeaf] !== undefined) {\r\n    return node[config.isLeaf] ?? false\r\n  }\r\n  return true\r\n}\r\n\r\n/**\r\n * 递归遍历树节点\r\n */\r\nexport function traverseTree(\r\n  nodes: TreeNodeData[],\r\n  callback: (node: TreeNodeData, parent: TreeNodeData | null) => void | boolean,\r\n  parent: TreeNodeData | null = null,\r\n  props: TreePropsConfig = {}\r\n): void {\r\n  for (const node of nodes) {\r\n    const result = callback(node, parent)\r\n    if (result === false) {\r\n      continue\r\n    }\r\n    const children = getNodeChildren(node, props)\r\n    if (children.length > 0) {\r\n      traverseTree(children, callback, node, props)\r\n    }\r\n  }\r\n}\r\n\r\n/**\r\n * 查找节点\r\n */\r\nexport function findNode(\r\n  nodes: TreeNodeData[],\r\n  predicate: (node: TreeNodeData) => boolean,\r\n  props: TreePropsConfig = {}\r\n): TreeNodeData | null {\r\n  for (const node of nodes) {\r\n    if (predicate(node)) {\r\n      return node\r\n    }\r\n    const children = getNodeChildren(node, props)\r\n    if (children.length > 0) {\r\n      const found = findNode(children, predicate, props)\r\n      if (found) return found\r\n    }\r\n  }\r\n  return null\r\n}\r\n\r\n/**\r\n * 根据 key 查找节点\r\n */\r\nexport function findNodeByKey(\r\n  nodes: TreeNodeData[],\r\n  key: string | number,\r\n  props: TreePropsConfig = {}\r\n): TreeNodeData | null {\r\n  return findNode(nodes, (node) => getNodeId(node, props) === key, props)\r\n}\r\n\r\n/**\r\n * 获取所有节点的 key\r\n */\r\nexport function getAllKeys(nodes: TreeNodeData[], props: TreePropsConfig = {}): (string | number)[] {\r\n  const keys: (string | number)[] = []\r\n  traverseTree(nodes, (node) => {\r\n    keys.push(getNodeId(node, props))\r\n  }, null, props)\r\n  return keys\r\n}\r\n\r\n/**\r\n * 获取所有叶子节点的 key\r\n */\r\nexport function getLeafKeys(nodes: TreeNodeData[], props: TreePropsConfig = {}): (string | number)[] {\r\n  const keys: (string | number)[] = []\r\n  traverseTree(nodes, (node) => {\r\n    if (isLeafNode(node, props)) {\r\n      keys.push(getNodeId(node, props))\r\n    }\r\n  }, null, props)\r\n  return keys\r\n}\r\n\r\n","<template>\r\n  <div class=\"vue-virtual-tree-node\" :class=\"{\r\n    'is-expanded': node.isExpanded,\r\n    'is-checked': node.isChecked,\r\n    'is-disabled': node.isDisabled,\r\n    'is-leaf': isLeaf,\r\n    'is-loading': node.isLoading,\r\n    'is-dragging': isDragging,\r\n    'is-current': isCurrent,\r\n    [`drop-${dropType}`]: dropType\r\n  }\" :style=\"{ paddingLeft: `${node.level * indent}px` }\" :draggable=\"draggable && !node.isDisabled\"\r\n    :data-node-id=\"node.id\" @dragstart=\"handleDragStart\" @dragenter=\"handleDragEnter\" @dragleave=\"handleDragLeave\"\r\n    @dragover=\"handleDragOver\" @dragend=\"handleDragEnd\" @drop=\"handleDrop\">\r\n    <div class=\"vue-virtual-tree-node__content\">\r\n      <span class=\"vue-virtual-tree-node__expand-icon\" :class=\"{ 'is-leaf': isLeaf, 'is-loading': node.isLoading }\">\r\n        <!-- 图标区域 -->\r\n        <span v-if=\"node.isLoading\">\r\n          <slot name=\"loading\" :node=\"node\" :data=\"node.data\">\r\n          </slot>\r\n        </span>\r\n\r\n        <slot v-else name=\"icon\" :node=\"node\" :data=\"node.data\">\r\n        </slot>\r\n      </span>\r\n      <span v-if=\"showCheckbox\" class=\"vue-virtual-tree-node__checkbox\">\r\n        <input type=\"checkbox\" :checked=\"node.isChecked\" :indeterminate=\"node.isIndeterminate\"\r\n          :disabled=\"node.isDisabled\" />\r\n      </span>\r\n      <span class=\"vue-virtual-tree-node__label\">\r\n        <slot :node=\"node\" :data=\"node.data\">\r\n          {{ label }}\r\n        </slot>\r\n      </span>\r\n    </div>\r\n  </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { computed, ref } from 'vue'\r\nimport type { FlatTreeNode, TreePropsConfig } from '../types'\r\nimport { getNodeLabel, isLeafNode } from '../utils/tree'\r\n\r\ninterface TreeNodeProps {\r\n  node: FlatTreeNode\r\n  props?: TreePropsConfig\r\n  showCheckbox?: boolean\r\n  expandOnClickNode?: boolean\r\n  draggable?: boolean\r\n  currentKey?: string | number | null\r\n  dropType?: 'prev' | 'inner' | 'next' | null\r\n  indent?: number | ((node: FlatTreeNode) => number)\r\n}\r\n\r\nconst props = defineProps<TreeNodeProps>()\r\n\r\nconst emit = defineEmits<{\r\n  'drag-start': [node: FlatTreeNode, event: DragEvent]\r\n  'drag-enter': [node: FlatTreeNode, event: DragEvent]\r\n  'drag-leave': [node: FlatTreeNode, event: DragEvent]\r\n  'drag-over': [node: FlatTreeNode, event: DragEvent]\r\n  'drag-end': [node: FlatTreeNode, event: DragEvent]\r\n  'drop': [node: FlatTreeNode, event: DragEvent]\r\n}>()\r\n\r\nconst isDragging = ref(false)\r\n\r\nconst label = computed(() => getNodeLabel(props.node.data, props.props))\r\nconst isLeaf = computed(() => isLeafNode(props.node.data, props.props))\r\nconst isCurrent = computed(() => props.currentKey !== null && props.currentKey !== undefined && props.currentKey === props.node.id)\r\nconst indent = computed(() => {\r\n  const indentProp = props.indent\r\n  if (typeof indentProp === 'function') {\r\n    try {\r\n      return indentProp(props.node) ?? 18\r\n    } catch {\r\n      return 18\r\n    }\r\n  }\r\n  return indentProp ?? 18\r\n})\r\n\r\n// click 事件已改为事件委托，在父组件 VirtualTree 中统一处理\r\n\r\nconst handleDragStart = (event: DragEvent) => {\r\n  if (props.node.isDisabled || !props.draggable) return\r\n  isDragging.value = true\r\n  emit('drag-start', props.node, event)\r\n}\r\n\r\nconst handleDragEnter = (event: DragEvent) => {\r\n  if (!props.draggable) return\r\n  emit('drag-enter', props.node, event)\r\n}\r\n\r\nconst handleDragLeave = (event: DragEvent) => {\r\n  if (!props.draggable) return\r\n  emit('drag-leave', props.node, event)\r\n}\r\n\r\nconst handleDragOver = (event: DragEvent) => {\r\n  if (!props.draggable) return\r\n  emit('drag-over', props.node, event)\r\n}\r\n\r\nconst handleDragEnd = (event: DragEvent) => {\r\n  isDragging.value = false\r\n  emit('drag-end', props.node, event)\r\n}\r\n\r\nconst handleDrop = (event: DragEvent) => {\r\n  if (!props.draggable) return\r\n  emit('drop', props.node, event)\r\n}\r\n</script>\r\n\r\n<style scoped lang=\"scss\">\r\n.vue-virtual-tree-node {\r\n  position: relative;\r\n  user-select: none;\r\n\r\n  &__content {\r\n    display: flex;\r\n    align-items: center;\r\n    min-height: 32px;\r\n    padding: 4px 8px 4px 0;\r\n    cursor: pointer;\r\n    transition: background-color 0.2s;\r\n\r\n    &:hover {\r\n      background-color: #f5f7fa;\r\n    }\r\n  }\r\n\r\n  &.is-disabled {\r\n    .vue-virtual-tree-node__content {\r\n      cursor: not-allowed;\r\n      color: #c0c4cc;\r\n    }\r\n  }\r\n\r\n  &__expand-icon {\r\n    display: inline-flex;\r\n    align-items: center;\r\n    justify-content: center;\r\n    width: 24px;\r\n    height: 24px;\r\n    margin-right: 4px;\r\n    transition: transform 0.2s;\r\n    color: #606266;\r\n    flex-shrink: 0;\r\n\r\n    &.is-leaf {\r\n      visibility: hidden;\r\n    }\r\n  }\r\n\r\n  &__checkbox {\r\n    margin-right: 8px;\r\n    flex-shrink: 0;\r\n\r\n    input[type='checkbox'] {\r\n      cursor: pointer;\r\n    }\r\n  }\r\n\r\n  &__label {\r\n    flex: 1;\r\n    word-wrap: break-word;\r\n    overflow-wrap: break-word;\r\n    line-height: 1.5;\r\n    min-width: 0; // 允许 flex 项目收缩\r\n  }\r\n\r\n  &.is-dragging {\r\n    opacity: 0.5;\r\n  }\r\n\r\n  &.drop-prev::before {\r\n    content: '';\r\n    position: absolute;\r\n    top: 0;\r\n    left: 0;\r\n    right: 0;\r\n    height: 2px;\r\n    background-color: #409eff;\r\n    z-index: 1;\r\n  }\r\n\r\n  &.drop-next::after {\r\n    content: '';\r\n    position: absolute;\r\n    bottom: 0;\r\n    left: 0;\r\n    right: 0;\r\n    height: 2px;\r\n    background-color: #409eff;\r\n    z-index: 1;\r\n  }\r\n\r\n  &.drop-inner {\r\n    background-color: #ecf5ff;\r\n  }\r\n\r\n  &.is-current {\r\n    .vue-virtual-tree-node__content {\r\n      background-color: #ecf5ff;\r\n      color: #409eff;\r\n      font-weight: 500;\r\n    }\r\n  }\r\n}\r\n</style>\r\n","import { ref, watch, computed } from 'vue'\r\nimport type { Ref } from 'vue'\r\nimport type { VirtualTreeProps, FlatTreeNode, TreeNodeData } from '../types'\r\nimport { getNodeId, getNodeChildren, isLeafNode } from '../utils/tree'\r\n\r\n/**\r\n * 树节点选择逻辑\r\n */\r\nexport function useTreeSelection(\r\n  props: VirtualTreeProps,\r\n  flatTree: Ref<FlatTreeNode[]>,\r\n  getNodeData: (id: string | number) => TreeNodeData | null,\r\n  getFlatNode: (id: string | number) => FlatTreeNode | null\r\n) {\r\n  // 从flatTree计算选中的节点key集合\r\n  const checkedKeys = computed(() => {\r\n    const keys = new Set<string | number>()\r\n    flatTree.value.forEach(node => {\r\n      if (node.isChecked) {\r\n        keys.add(node.id)\r\n      }\r\n    })\r\n    return keys\r\n  })\r\n\r\n  // 从flatTree计算半选状态的节点key集合\r\n  const halfCheckedKeys = computed(() => {\r\n    const keys = new Set<string | number>()\r\n    flatTree.value.forEach(node => {\r\n      if (node.isIndeterminate) {\r\n        keys.add(node.id)\r\n      }\r\n    })\r\n    return keys\r\n  })\r\n  // 当前选中的节点 key（单选）\r\n  const selectedKey = ref<string | number | null>(null)\r\n  // 当前选中的节点数据\r\n  const currentNode = ref<TreeNodeData | null>(null)\r\n\r\n  // 初始化选中的节点（处理父子关联和半选状态）\r\n  const initNodeChecked = () => {\r\n    // 先清除所有节点的选中状态和半选状态\r\n    flatTree.value.forEach(node => {\r\n      node.isChecked = false\r\n      node.isIndeterminate = false\r\n    })\r\n\r\n     // 如果有默认选中的节点，设置它们并处理父子关联\r\n     if (props.defaultCheckedKeys && props.defaultCheckedKeys.length > 0) {\r\n      props.defaultCheckedKeys.forEach(key => {\r\n        const node = getFlatNode(key)\r\n        if (node) {\r\n          setNodeChecked(key, true)\r\n        }\r\n      })\r\n    }\r\n  }\r\n\r\n  // 初始化当前选中节点\r\n  const initCurrentNode = () => {\r\n    if (props.currentNodeKey !== undefined) {\r\n      selectedKey.value = props.currentNodeKey\r\n      const node = getNodeData(props.currentNodeKey)\r\n      currentNode.value = node\r\n    }\r\n  }\r\n\r\n  // 获取节点的所有子节点 key（从原始数据递归获取，包括未展开的子节点）\r\n  const getAllChildrenKeys = (nodeId: string | number): (string | number)[] => {\r\n    const keys: (string | number)[] = []\r\n    const nodeData = getNodeData(nodeId)\r\n    if (!nodeData) return keys\r\n\r\n    // 从原始数据递归获取所有子节点\r\n    const traverse = (data: TreeNodeData) => {\r\n      const children = getNodeChildren(data, props.props)\r\n      children.forEach(child => {\r\n        const childId = getNodeId(child, props.props)\r\n        keys.push(childId)\r\n        // 递归获取子节点的子节点\r\n        traverse(child)\r\n      })\r\n    }\r\n\r\n    traverse(nodeData)\r\n    return keys\r\n  }\r\n\r\n\r\n  // 更新半选状态\r\n  const updateHalfCheckedKeys = () => {\r\n    halfCheckedKeys.value.clear()\r\n    const allKeys = new Set(flatTree.value.map(n => n.id))\r\n\r\n    for (const key of allKeys) {\r\n      const childrenKeys = getAllChildrenKeys(key)\r\n      if (childrenKeys.length === 0) continue\r\n\r\n      const checkedChildren = childrenKeys.filter(k => checkedKeys.value.has(k))\r\n      if (checkedChildren.length > 0 && checkedChildren.length < childrenKeys.length) {\r\n        halfCheckedKeys.value.add(key)\r\n      }\r\n    }\r\n  }\r\n\r\n  // 直接操作flatTree中的节点状态\r\n  const setNodeCheckedInTree = (node: FlatTreeNode, checked: boolean) => {\r\n    node.isChecked = checked\r\n    node.isIndeterminate = false\r\n\r\n    // 递归处理子节点\r\n    const setChildrenChecked = (parentNode: FlatTreeNode, checkedState: boolean) => {\r\n      if (parentNode.children) {\r\n        parentNode.children.forEach(child => {\r\n          child.isChecked = checkedState\r\n          child.isIndeterminate = false\r\n          setChildrenChecked(child, checkedState)\r\n        })\r\n      }\r\n    }\r\n    setChildrenChecked(node, checked)\r\n\r\n    // 更新父节点的选中状态\r\n    const updateParentChecked = (childNode: FlatTreeNode) => {\r\n      const parentId = childNode.parentId\r\n      if (parentId !== null) {\r\n        const parent = getFlatNode(parentId)\r\n        if (parent) {\r\n          const siblings = parent.children || []\r\n          const checkedCount = siblings.filter(n => n.isChecked).length\r\n          const indeterminateCount = siblings.filter(n => n.isIndeterminate).length\r\n\r\n          if (checkedCount === siblings.length) {\r\n            // 所有子节点都选中\r\n            parent.isChecked = true\r\n            parent.isIndeterminate = false\r\n          } else if (checkedCount === 0 && indeterminateCount === 0) {\r\n            // 所有子节点都未选中\r\n            parent.isChecked = false\r\n            parent.isIndeterminate = false\r\n          } else {\r\n            // 部分选中\r\n            parent.isChecked = false\r\n            parent.isIndeterminate = true\r\n          }\r\n\r\n          // 递归更新父节点\r\n          updateParentChecked(parent)\r\n        }\r\n      }\r\n    }\r\n    updateParentChecked(node)\r\n  }\r\n\r\n  // 设置节点选中状态（考虑父子关联）\r\n  const setNodeChecked = (nodeId: string | number, checked: boolean, checkStrictly?: boolean) => {\r\n    const node = getFlatNode(nodeId)\r\n    if (!node) return\r\n\r\n    const isStrictly = checkStrictly ?? props.checkStrictly ?? false\r\n\r\n    if (isStrictly) {\r\n      // 严格模式：只设置当前节点\r\n      node.isChecked = checked\r\n      node.isIndeterminate = false\r\n    } else {\r\n      // 非严格模式：关联父子节点\r\n      setNodeCheckedInTree(node, checked)\r\n    }\r\n  }\r\n\r\n  // 切换节点选中状态\r\n  const toggleNodeChecked = (nodeId: string | number) => {\r\n    const isChecked = checkedKeys.value.has(nodeId)\r\n    setNodeChecked(nodeId, !isChecked)\r\n  }\r\n\r\n  // 设置当前选中节点\r\n  const setCurrentNode = (key: string | number | null, node: TreeNodeData | null = null) => {\r\n    selectedKey.value = key\r\n    currentNode.value = node\r\n  }\r\n\r\n  // 获取选中的节点数据\r\n  const getCheckedNodes = (leafOnly: boolean = false, includeHalfChecked: boolean = false): TreeNodeData[] => {\r\n    const nodes: TreeNodeData[] = []\r\n    const keys = includeHalfChecked\r\n      ? new Set([...checkedKeys.value, ...halfCheckedKeys.value])\r\n      : checkedKeys.value\r\n\r\n    for (const key of keys) {\r\n      const node = getNodeData(key)\r\n      if (!node) continue\r\n\r\n      if (leafOnly) {\r\n        const children = getNodeChildren(node, props.props)\r\n        if (children.length === 0) {\r\n          nodes.push(node)\r\n        }\r\n      } else {\r\n        nodes.push(node)\r\n      }\r\n    }\r\n\r\n    return nodes\r\n  }\r\n\r\n  // 获取选中的节点 key\r\n  const getCheckedKeys = (leafOnly: boolean = false): (string | number)[] => {\r\n    if (leafOnly) {\r\n      const leafNodes = getCheckedNodes(true)\r\n      return leafNodes.map(node => getNodeId(node, props.props))\r\n    }\r\n    return Array.from(checkedKeys.value)\r\n  }\r\n\r\n  // 设置选中的节点\r\n  const setCheckedNodes = (nodes: TreeNodeData[], leafOnly: boolean = false) => {\r\n    checkedKeys.value.clear()\r\n    const keys = nodes\r\n      .filter(node => {\r\n        if (leafOnly) {\r\n          return isLeafNode(node, props.props)\r\n        }\r\n        return true\r\n      })\r\n      .map(node => getNodeId(node, props.props))\r\n    keys.forEach(key => {\r\n      setNodeChecked(key, true)\r\n    })\r\n    if (!props.checkStrictly) {\r\n      updateHalfCheckedKeys()\r\n    }\r\n  }\r\n\r\n  // 设置选中的节点 key\r\n  const setCheckedKeys = (keys: (string | number)[], leafOnly: boolean = false) => {\r\n    checkedKeys.value.clear()\r\n    const keysToSet = leafOnly\r\n      ? keys.filter(key => {\r\n          const node = getNodeData(key)\r\n          return node && isLeafNode(node, props.props)\r\n        })\r\n      : keys\r\n    keysToSet.forEach(key => {\r\n      setNodeChecked(key, true)\r\n    })\r\n    if (!props.checkStrictly) {\r\n      updateHalfCheckedKeys()\r\n    }\r\n  }\r\n\r\n  // 初始化\r\n  initCurrentNode()\r\n\r\n  // 选中状态现在直接在flatTree中管理，不需要额外的监听器\r\n\r\n  // 监听 props.currentNodeKey 变化\r\n  watch(\r\n    () => props.currentNodeKey,\r\n    (newKey) => {\r\n      if (newKey !== undefined) {\r\n        setCurrentNode(newKey, getNodeData(newKey))\r\n      }\r\n    }\r\n  )\r\n\r\n  return {\r\n    checkedKeys,\r\n    halfCheckedKeys,\r\n    selectedKey,\r\n    currentNode,\r\n    initNodeChecked,\r\n    setNodeChecked,\r\n    toggleNodeChecked,\r\n    setCurrentNode,\r\n    getCheckedNodes,\r\n    getCheckedKeys,\r\n    setCheckedNodes,\r\n    setCheckedKeys,\r\n    updateHalfCheckedKeys\r\n  }\r\n}\r\n\r\n","import { ref, type Ref } from 'vue'\r\nimport type { VirtualTreeProps, FlatTreeNode } from '../types'\r\nimport { getAllKeys } from '../utils/tree'\r\n\r\n/**\r\n * 树节点展开/折叠逻辑\r\n */\r\nexport function useTreeExpand(\r\n  props: VirtualTreeProps,\r\n  flatTree: Ref<FlatTreeNode[]>,\r\n  visibleNodes: Ref<FlatTreeNode[]>,\r\n  refreshVisibleIndexes: () => void\r\n) {\r\n\r\n  const expandedKeys = ref<Set<string | number>>(new Set())\r\n\r\n  // 初始化展开的节点\r\n  const initExpandedKeys = () => {\r\n    // 重置展开状态\r\n    if (props.defaultExpandAll) {\r\n      const allKeys = getAllKeys(props.data, props.props)\r\n      expandedKeys.value = new Set(allKeys)\r\n    } else if (props.defaultExpandedKeys && props.defaultExpandedKeys.length > 0) {\r\n      expandedKeys.value = new Set(props.defaultExpandedKeys)\r\n    } else {\r\n      expandedKeys.value = new Set()\r\n    }\r\n  }\r\n\r\n  const collectVisibleDescendants = (parent: FlatTreeNode): FlatTreeNode[] => {\r\n    const result: FlatTreeNode[] = []\r\n    if (!parent.children) return result\r\n    parent.children.forEach(child => {\r\n      result.push(child)\r\n      if (child.isExpanded) {\r\n        result.push(...collectVisibleDescendants(child))\r\n      }\r\n    })\r\n    return result\r\n  }\r\n\r\n  const expandVisibleNode = (node: FlatTreeNode) => {\r\n    if (typeof node.visibleIndex !== 'number') return\r\n    const descendants = collectVisibleDescendants(node)\r\n    if (descendants.length === 0) return\r\n    visibleNodes.value.splice(node.visibleIndex + 1, 0, ...descendants)\r\n    refreshVisibleIndexes()\r\n  }\r\n  const collapseVisibleNode = (node: FlatTreeNode) => {\r\n    if (typeof node.visibleIndex !== 'number') return\r\n    const children = collectVisibleDescendants(node)\r\n    if (children.length === 0) return\r\n    visibleNodes.value.splice(node.visibleIndex + 1, children.length)\r\n    refreshVisibleIndexes()\r\n  }\r\n\r\n  /**\r\n   * 展开节点\r\n   */\r\n  const expandNode = (node: FlatTreeNode) => {\r\n    if (props.accordion) {\r\n      // 手风琴模式：折叠同级其他节点\r\n      // 查找兄弟节点（需要从flatTree中查找，因为node.parentId可能为null）\r\n      const siblings = flatTree.value.filter(\r\n        n => n.parentId === node.parentId && n.id !== node.id && n.isExpanded\r\n      )\r\n      siblings.forEach(sibling => {\r\n        sibling.isExpanded = false\r\n        expandedKeys.value.delete(sibling.id)\r\n        collapseVisibleNode(sibling)\r\n      })\r\n    }\r\n\r\n    // 展开当前节点\r\n    node.isExpanded = true\r\n    expandedKeys.value.add(node.id)\r\n    expandVisibleNode(node)\r\n  }\r\n\r\n  const setRecursionExpanded = (node: FlatTreeNode, isExpanded: boolean) => {\r\n    node.isExpanded = isExpanded\r\n    if (isExpanded) {\r\n      expandedKeys.value.add(node.id)\r\n    } else {\r\n      expandedKeys.value.delete(node.id)\r\n    }\r\n    if (node.children) {\r\n      node.children.forEach(child => {\r\n        setRecursionExpanded(child, isExpanded)\r\n      })\r\n    }\r\n  }\r\n  /**\r\n   * 折叠节点\r\n   */\r\n  const collapseNode = (node: FlatTreeNode) => {\r\n    collapseVisibleNode(node)\r\n    setRecursionExpanded(node, false)\r\n  }\r\n\r\n  /**\r\n   * 切换节点展开状态\r\n   */\r\n  const toggleNode = (node: FlatTreeNode) => {\r\n    if (node.isExpanded) {\r\n      collapseNode(node)\r\n    } else {\r\n      expandNode(node)\r\n    }\r\n  }\r\n\r\n  return {\r\n    expandedKeys,\r\n    initExpandedKeys,\r\n    expandNode,\r\n    collapseNode,\r\n    toggleNode\r\n  }\r\n}\r\n\r\n","import { ref, type Ref } from 'vue'\r\nimport type { VirtualTreeProps, FlatTreeNode } from '../types'\r\nimport { getNodeLabel } from '../utils/tree'\r\n\r\n/**\r\n * 归并排序：按 index 从小到大排序\r\n */\r\nfunction mergeSort(nodes: FlatTreeNode[]): FlatTreeNode[] {\r\n  if (nodes.length <= 1) {\r\n    return nodes\r\n  }\r\n\r\n  const mid = Math.floor(nodes.length / 2)\r\n  const left = mergeSort(nodes.slice(0, mid))\r\n  const right = mergeSort(nodes.slice(mid))\r\n\r\n  return merge(left, right)\r\n}\r\n\r\n/**\r\n * 合并两个有序数组\r\n */\r\nfunction merge(left: FlatTreeNode[], right: FlatTreeNode[]): FlatTreeNode[] {\r\n  const result: FlatTreeNode[] = []\r\n  let i = 0\r\n  let j = 0\r\n\r\n  while (i < left.length && j < right.length) {\r\n    if (left[i].index <= right[j].index) {\r\n      result.push(left[i])\r\n      i++\r\n    } else {\r\n      result.push(right[j])\r\n      j++\r\n    }\r\n  }\r\n\r\n  // 将剩余元素添加到结果数组\r\n  while (i < left.length) {\r\n    result.push(left[i])\r\n    i++\r\n  }\r\n\r\n  while (j < right.length) {\r\n    result.push(right[j])\r\n    j++\r\n  }\r\n\r\n  return result\r\n}\r\n\r\n/**\r\n * 树节点过滤逻辑\r\n */\r\nexport function useTreeFilter(\r\n  props: VirtualTreeProps,\r\n  flatTree: Ref<FlatTreeNode[]>,\r\n  flatNodeMap: Ref<Map<string | number, FlatTreeNode>>,\r\n  filteredFlatTree: Ref<FlatTreeNode[]>,\r\n  filteredFlatNodeMap: Ref<Map<string | number, FlatTreeNode>>,\r\n  isFiltered: Ref<boolean>,\r\n  expandedKeys: Ref<Set<string | number>>,\r\n  setVisibleNodes: (nodes: FlatTreeNode[]) => void\r\n) {\r\n\r\n  const rebuildVisibleNodes = () => {\r\n    const roots = flatTree.value.filter(node => node.parentId === null)\r\n    const result: FlatTreeNode[] = []\r\n    const traverse = (node: FlatTreeNode) => {\r\n      result.push(node)\r\n      if (node.isExpanded && node.children) {\r\n        node.children.forEach(child => traverse(child))\r\n      }\r\n    }\r\n    roots.forEach(root => traverse(root))\r\n    setVisibleNodes(result)\r\n  }\r\n\r\n  // 默认过滤方法\r\n  const defaultFilterMethod = (value: string, data: any): boolean => {\r\n    if (!value) return true\r\n    const label = getNodeLabel(data, props.props)\r\n    return label.toLowerCase().includes(value.toLowerCase())\r\n  }\r\n  /**\r\n   * 克隆节点（浅拷贝基本属性，children 需要重新构造）\r\n   */\r\n  const cloneNode = (node: FlatTreeNode): FlatTreeNode => {\r\n    return {\r\n      ...node,\r\n      children: undefined // children 需要重新构造\r\n    }\r\n  }\r\n\r\n  const filterText = ref('')\r\n  // 过滤节点\r\n  const filter = (value: string) => {\r\n    filterText.value = value\r\n    filteredFlatTree.value = [];\r\n    filteredFlatNodeMap.value = new Map();\r\n    if (!value) {\r\n      isFiltered.value = false \r\n      flatTree.value.forEach(node => {\r\n        if (!node.isLeaf) {\r\n          node.isExpanded = true\r\n          expandedKeys.value.add(node.id)\r\n        }\r\n      })\r\n      rebuildVisibleNodes()\r\n      return Promise.resolve()\r\n    }\r\n    isFiltered.value = true\r\n    expandedKeys.value.clear()\r\n    return new Promise(async (resolve) => {\r\n      const filterMethod = props.filterNodeMethod || defaultFilterMethod\r\n\r\n      // 第一步：收集所有匹配的节点（包括需要显示的父节点），并克隆它们\r\n      const clonedNodes = new Map<string | number, FlatTreeNode>()\r\n\r\n      // 收集直接匹配的节点并克隆\r\n      flatTree.value.forEach(node => {\r\n        if (filterMethod(value, node.data)) {\r\n          // 克隆匹配的节点\r\n          if (!clonedNodes.has(node.id)) {\r\n            clonedNodes.set(node.id, cloneNode(node))\r\n          }\r\n\r\n          // 收集并克隆所有父节点\r\n          let parentId: string | number | null = node.parentId\r\n          while (parentId) {\r\n            const parentNode = flatNodeMap.value.get(parentId)\r\n            if (parentNode && !clonedNodes.has(parentId)) {\r\n              clonedNodes.set(parentId, cloneNode(parentNode))\r\n            }\r\n            parentId = parentNode?.parentId || null\r\n          }\r\n        }\r\n      })\r\n\r\n      // 第二步：根据 parentId 关系重建每个节点的 children 属性\r\n      clonedNodes.forEach((clonedNode) => {\r\n        filteredFlatNodeMap.value.set(clonedNode.id, clonedNode)\r\n        // 查找所有子节点（在 clonedNodes 中的）\r\n        const children: FlatTreeNode[] = []\r\n        clonedNodes.forEach((childNode) => {\r\n          if (childNode.parentId === clonedNode.id) {\r\n            children.push(childNode)\r\n          }\r\n        })\r\n\r\n        // 按 index 排序子节点，保持原始顺序\r\n        if (children.length > 0) {\r\n          clonedNode.children = mergeSort(children)\r\n          clonedNode.isExpanded = true\r\n          expandedKeys.value.add(clonedNode.id)\r\n        } else {\r\n          clonedNode.children = undefined\r\n          clonedNode.isLeaf = true\r\n        }\r\n      })\r\n\r\n\r\n      // 第三步：按 index 排序\r\n      const sortedNodes = mergeSort(Array.from(clonedNodes.values()))\r\n\r\n      setVisibleNodes(sortedNodes)\r\n      filteredFlatTree.value = sortedNodes\r\n      resolve(void 0)\r\n    })\r\n  }\r\n  // 清空过滤\r\n  const clearFilter = () => {\r\n    filter('')\r\n  }\r\n\r\n  return {\r\n    filterText,\r\n    filter,\r\n    clearFilter\r\n  }\r\n}\r\n\r\n","import { ref } from 'vue'\r\nimport type { VirtualTreeProps, FlatTreeNode, TreeNodeData } from '../types'\r\nimport { getNodeId, getNodeChildren } from '../utils/tree'\r\n\r\n/**\r\n * 拖拽类型\r\n */\r\nexport type DropType = 'prev' | 'inner' | 'next'\r\n\r\n/**\r\n * 树节点拖拽逻辑\r\n */\r\nexport function useTreeDrag(\r\n  props: VirtualTreeProps,\r\n  getNodeData: (id: string | number) => TreeNodeData | null\r\n) {\r\n  const draggingNode = ref<FlatTreeNode | null>(null)\r\n  const dropNode = ref<FlatTreeNode | null>(null)\r\n  const dropType = ref<DropType | null>(null)\r\n\r\n  // 默认允许拖拽\r\n  const defaultAllowDrag = (_node: TreeNodeData): boolean => {\r\n    return true\r\n  }\r\n\r\n  // 默认允许放置\r\n  const defaultAllowDrop = (\r\n    draggingNode: TreeNodeData,\r\n    dropNode: TreeNodeData,\r\n    type: DropType,\r\n    props: VirtualTreeProps\r\n  ): boolean => {\r\n    // 不能拖拽到自己内部\r\n    if (type === 'inner') {\r\n      const draggingId = getNodeId(draggingNode, props.props)\r\n      const isDescendant = (node: TreeNodeData): boolean => {\r\n        if (getNodeId(node, props.props) === draggingId) return true\r\n        const children = getNodeChildren(node, props.props)\r\n        return children.some(child => isDescendant(child))\r\n      }\r\n      return !isDescendant(dropNode)\r\n    }\r\n    return true\r\n  }\r\n\r\n  // 开始拖拽\r\n  const handleDragStart = (node: FlatTreeNode, event: DragEvent) => {\r\n    draggingNode.value = node\r\n    if (event.dataTransfer) {\r\n      event.dataTransfer.effectAllowed = 'move'\r\n    }\r\n  }\r\n\r\n  // 拖拽进入\r\n  const handleDragEnter = (node: FlatTreeNode, event: DragEvent) => {\r\n    if (!draggingNode.value) return\r\n\r\n    const draggingData = getNodeData(draggingNode.value.id)\r\n    const dropData = getNodeData(node.id)\r\n\r\n    if (!draggingData || !dropData) return\r\n\r\n    // 判断是否允许拖拽\r\n    const allowDrag = props.allowDrag || defaultAllowDrag\r\n    if (!allowDrag(draggingData)) {\r\n      return\r\n    }\r\n\r\n    dropNode.value = node\r\n\r\n    // 计算拖拽位置类型\r\n    const rect = (event.currentTarget as HTMLElement).getBoundingClientRect()\r\n    const y = event.clientY - rect.top\r\n    const height = rect.height\r\n    const threshold = height / 3\r\n\r\n    if (y < threshold) {\r\n      dropType.value = 'prev'\r\n    } else if (y > height - threshold) {\r\n      dropType.value = 'next'\r\n    } else {\r\n      dropType.value = 'inner'\r\n    }\r\n\r\n    // 判断是否允许放置\r\n    const allowDrop = props.allowDrop || ((dragging, dropping, type) => defaultAllowDrop(dragging, dropping, type, props))\r\n    if (!allowDrop(draggingData, dropData, dropType.value)) {\r\n      dropType.value = null\r\n      return\r\n    }\r\n\r\n    event.preventDefault()\r\n  }\r\n\r\n  // 拖拽离开\r\n  const handleDragLeave = (node: FlatTreeNode, event: DragEvent) => {\r\n    // 检查是否真的离开了节点（而不是进入子元素）\r\n    const relatedTarget = event.relatedTarget as HTMLElement\r\n    if (relatedTarget && (event.currentTarget as HTMLElement).contains(relatedTarget)) {\r\n      return\r\n    }\r\n    if (dropNode.value?.id === node.id) {\r\n      dropNode.value = null\r\n      dropType.value = null\r\n    }\r\n  }\r\n\r\n  // 拖拽悬停\r\n  const handleDragOver = (node: FlatTreeNode, event: DragEvent) => {\r\n    if (!draggingNode.value || !dropNode.value || dropNode.value.id !== node.id) return\r\n\r\n    const draggingData = getNodeData(draggingNode.value.id)\r\n    const dropData = getNodeData(node.id)\r\n\r\n    if (!draggingData || !dropData) return\r\n\r\n    // 计算拖拽位置类型\r\n    const rect = (event.currentTarget as HTMLElement).getBoundingClientRect()\r\n    const y = event.clientY - rect.top\r\n    const height = rect.height\r\n    const threshold = height / 3\r\n\r\n    let newDropType: DropType\r\n    if (y < threshold) {\r\n      newDropType = 'prev'\r\n    } else if (y > height - threshold) {\r\n      newDropType = 'next'\r\n    } else {\r\n      newDropType = 'inner'\r\n    }\r\n\r\n    // 判断是否允许放置\r\n    const allowDrop = props.allowDrop || ((dragging, dropping, type) => defaultAllowDrop(dragging, dropping, type, props))\r\n    if (!allowDrop(draggingData, dropData, newDropType)) {\r\n      dropType.value = null\r\n      event.preventDefault()\r\n      return\r\n    }\r\n\r\n    dropType.value = newDropType\r\n    event.preventDefault()\r\n  }\r\n\r\n  // 拖拽结束\r\n  const handleDragEnd = (_node: FlatTreeNode, _event: DragEvent) => {\r\n    draggingNode.value = null\r\n    dropNode.value = null\r\n    dropType.value = null\r\n  }\r\n\r\n  // 放置\r\n  const handleDrop = (node: FlatTreeNode, _event: DragEvent) => {\r\n    if (!draggingNode.value || !dropNode.value || dropType.value === null) {\r\n      return\r\n    }\r\n\r\n    const draggingData = getNodeData(draggingNode.value.id)\r\n    const dropData = getNodeData(node.id)\r\n\r\n    if (!draggingData || !dropData) return\r\n\r\n    // 判断是否允许放置\r\n    const allowDrop = props.allowDrop || ((dragging, dropping, type) => defaultAllowDrop(dragging, dropping, type, props))\r\n    if (!allowDrop(draggingData, dropData, dropType.value)) {\r\n      return\r\n    }\r\n\r\n    // 这里不直接修改数据，而是通过事件通知父组件\r\n    // 父组件负责更新数据\r\n\r\n    draggingNode.value = null\r\n    dropNode.value = null\r\n    const finalDropType = dropType.value\r\n    dropType.value = null\r\n\r\n    return {\r\n      draggingNode: draggingData,\r\n      dropNode: dropData,\r\n      dropType: finalDropType\r\n    }\r\n  }\r\n\r\n  return {\r\n    draggingNode,\r\n    dropNode,\r\n    dropType,\r\n    handleDragStart,\r\n    handleDragEnter,\r\n    handleDragLeave,\r\n    handleDragOver,\r\n    handleDragEnd,\r\n    handleDrop\r\n  }\r\n}\r\n\r\n","import { computed, nextTick, onUnmounted, ref, watch } from 'vue'\r\nimport type { TreeNodeData, FlatTreeNode, TreePropsConfig, VirtualTreeProps, VirtualTreeEmits } from '../types'\r\nimport { getNodeId, getNodeChildren, isNodeDisabled, isLeafNode } from '../utils/tree'\r\nimport { useTreeSelection } from '../composables/useTreeSelection'\r\nimport { useTreeExpand } from './useTreeExpand'\r\nimport { useTreeFilter } from './useTreeFilter'\r\nimport { useTreeDrag } from './useTreeDrag'\r\n\r\n/**\r\n * Emit function type helper\r\n */\r\ntype EmitFn<T> = <K extends keyof T>(event: K, ...args: T[K] extends any[] ? T[K] : never) => void\r\n\r\n/**\r\n * 扁平化树形数据\r\n */\r\nexport function useTreeData(props: VirtualTreeProps, emit: EmitFn<VirtualTreeEmits>) {\r\n\r\n  const flatTree = ref<FlatTreeNode[]>([])\r\n  const rawData = ref<TreeNodeData[]>(props.data)\r\n  // 使用 Map 建立索引，O(1) 查找\r\n  const flatNodeMap = ref<Map<string | number, FlatTreeNode>>(new Map())\r\n  const visibleNodes = ref<FlatTreeNode[]>([])\r\n  const filteredFlatTree = ref<FlatTreeNode[]>([])\r\n  const filteredFlatNodeMap = ref<Map<string | number, FlatTreeNode>>(new Map())\r\n  const isFiltered = ref(false)\r\n  const treeDataWrapper = computed(() => {\r\n    return isFiltered.value ? filteredFlatTree.value : flatTree.value\r\n  })\r\n  const treeDataMapWrapper = computed(() => {\r\n    return isFiltered.value ? filteredFlatNodeMap.value : flatNodeMap.value\r\n  })\r\n  const refreshVisibleIndexes = () => {\r\n    visibleNodes.value.forEach((node, index) => {\r\n      node.visibleIndex = index\r\n    })\r\n  }\r\n  const setVisibleNodes = (nodes: FlatTreeNode[]) => {\r\n    visibleNodes.value = nodes\r\n    refreshVisibleIndexes()\r\n  }\r\n\r\n  // 根据 key 获取节点数据\r\n  const getNodeData = (id: string | number): TreeNodeData | null => {\r\n    const flatNode = treeDataMapWrapper.value.get(id)\r\n    return flatNode ? flatNode.data : null\r\n  }\r\n\r\n  // 根据 key 获取扁平节点\r\n  const getFlatNode = (id: string | number): FlatTreeNode | null => {\r\n    return treeDataMapWrapper.value.get(id) || null\r\n  }\r\n\r\n  // 选择逻辑\r\n  const {\r\n    checkedKeys,\r\n    halfCheckedKeys,\r\n    selectedKey,\r\n    currentNode,\r\n    toggleNodeChecked,\r\n    setCurrentNode: setSelectionCurrentNode,\r\n    getCheckedNodes,\r\n    getCheckedKeys,\r\n    setCheckedNodes,\r\n    setCheckedKeys,\r\n    initNodeChecked\r\n  } = useTreeSelection(props, flatTree, getNodeData, getFlatNode)\r\n\r\n  // 展开/折叠逻辑\r\n  const { expandNode, collapseNode, expandedKeys, initExpandedKeys } = useTreeExpand(\r\n    props,\r\n    treeDataWrapper,\r\n    visibleNodes,\r\n    refreshVisibleIndexes\r\n  )\r\n\r\n  // 过滤逻辑\r\n  const { filter } = useTreeFilter(props, flatTree, flatNodeMap, filteredFlatTree, filteredFlatNodeMap, isFiltered, expandedKeys, setVisibleNodes)\r\n\r\n  // 拖拽逻辑\r\n  const dragState = useTreeDrag(props, getNodeData)\r\n\r\n  // 扁平化树形数据\r\n  const flattenTree = (\r\n    nodes: TreeNodeData[],\r\n    level: number = 0,\r\n    parentNode: FlatTreeNode | null = null,\r\n    startIndex: number = 0,\r\n    visible: boolean = true,\r\n    config?: TreePropsConfig\r\n  ): { nodes: FlatTreeNode[], flatNodes: FlatTreeNode[], nodeMap: Map<string | number, FlatTreeNode>, visibleNodes: FlatTreeNode[] } => {\r\n    const map = new Map<string | number, FlatTreeNode>()\r\n    const visibleList: FlatTreeNode[] = []\r\n    function genenrateFlatNodes(nodes: TreeNodeData[],\r\n      level: number = 0,\r\n      parentNode: FlatTreeNode | null = null,\r\n      startIndex: number = 0,\r\n      visible: boolean = true,\r\n      container: FlatTreeNode[] = [],\r\n      config?: TreePropsConfig) {\r\n      const result: FlatTreeNode[] = [];\r\n      let length = nodes.length;\r\n      for (let i = 0; i < length; i++) {\r\n        startIndex++;\r\n        const node: TreeNodeData = nodes[i]\r\n        const id = getNodeId(node, config)\r\n        const children = getNodeChildren(node, config)\r\n        const isExpanded = expandedKeys.value.has(id)\r\n        const isLeaf = isLeafNode(node, config)\r\n\r\n        const flatNode: FlatTreeNode = {\r\n          id,\r\n          data: node,\r\n          level,\r\n          parentId: parentNode?.id || null,\r\n          index: startIndex,\r\n          isExpanded,\r\n          isDisabled: isNodeDisabled(node, config),\r\n          isLeaf: isLeaf,\r\n          isLoading: false,\r\n          isLoaded: false,\r\n          isChecked: false,\r\n          rawChildren: children.length > 0 ? children : undefined\r\n        }\r\n        result.push(flatNode)\r\n        container.push(flatNode)\r\n        if (visible) {\r\n          visibleList.push(flatNode)\r\n        }\r\n        // 如果节点展开且有子节点，递归处理子节点\r\n        if (children.length > 0) {\r\n          const { nodes: childNodes, index } = genenrateFlatNodes(children, level + 1, flatNode, startIndex, isExpanded && visible, container, config)\r\n          flatNode.children = childNodes\r\n          startIndex = index\r\n        }\r\n        map.set(id, flatNode);\r\n      }\r\n\r\n      return { nodes: result, index: startIndex }\r\n    }\r\n\r\n    const container: FlatTreeNode[] = []\r\n    const { nodes: result } = genenrateFlatNodes(nodes, level, parentNode, startIndex, visible, container, config)\r\n    return { nodes: result, flatNodes: container, nodeMap: map, visibleNodes: visibleList }\r\n  }\r\n\r\n  // 更新扁平化数据 - 优化大数据量的性能\r\n  // 防抖更新标记\r\n  let updatePending = false\r\n  const updateFlatTree = () => {\r\n    if (updatePending) return // 如果已经有更新在等待中，跳过\r\n    updatePending = true\r\n    const { flatNodes, nodeMap, visibleNodes: visibleNodesResult } = flattenTree(rawData.value, 0, null, 0, true, props.props)\r\n    flatTree.value = flatNodes\r\n    flatNodeMap.value = nodeMap\r\n    setVisibleNodes(visibleNodesResult)\r\n    updatePending = false\r\n  }\r\n\r\n  const insertFlatTree = (node: FlatTreeNode, children: TreeNodeData[]) => {\r\n    const { nodes: result, flatNodes: container, nodeMap } = flattenTree(\r\n      children,\r\n      node.level + 1,\r\n      node,\r\n      node.index + 1,\r\n      true,\r\n      props.props\r\n    )\r\n    node.children = result\r\n    nodeMap.forEach((value, key) => {\r\n      flatNodeMap.value.set(key, value);\r\n    })\r\n    flatTree.value.splice(node.index + 1, 0, ...container)\r\n    requestAnimationFrame(() => {\r\n      for (let i = node.index + container.length; i < flatTree.value.length; i++) {\r\n        const child = flatTree.value[i]\r\n        child.index = i\r\n      }\r\n    })\r\n  }\r\n  const regenerateState: RegenerateOptions = {\r\n    needEmit: true,\r\n    resetExpanded: true,\r\n    resetChecked: true\r\n  }\r\n  // 只在数据变化时重新生成flatTree\r\n  watch(\r\n    () => props.data,\r\n    (newData) => {\r\n      rawData.value = newData\r\n      regenerateState.needEmit = true\r\n      regenerateState.resetChecked = true\r\n      regenerateFlatTree()\r\n    },\r\n    { deep: true }\r\n  )\r\n\r\n  // 监听 defaultExpandedKeys 和 defaultExpandAll 变化时重新生成\r\n  watch(\r\n    () => [props.defaultExpandedKeys, props.defaultExpandAll],\r\n    () => {\r\n      regenerateState.resetExpanded = true\r\n      regenerateFlatTree()\r\n    },\r\n    { deep: true, immediate: false }\r\n  )\r\n\r\n  // 监听 defaultCheckedKeys 变化时重新生成\r\n  watch(\r\n    () => props.defaultCheckedKeys,\r\n    () => {\r\n      regenerateState.resetChecked = true\r\n      regenerateFlatTree()\r\n    },\r\n    { deep: true, immediate: false }\r\n  )\r\n  let regenerateTimer: ReturnType<typeof setTimeout> | null = null\r\n\r\n\r\n  type RegenerateOptions = {\r\n    resetExpanded?: boolean\r\n    resetChecked?: boolean\r\n    needEmit?: boolean\r\n  }\r\n\r\n  // 重新生成flatTree的函数（只在必要时调用）\r\n  const regenerateFlatTree = () => {\r\n    if (regenerateTimer) {\r\n      clearTimeout(regenerateTimer)\r\n    }\r\n    regenerateTimer = setTimeout(() => {\r\n      if (regenerateState.resetExpanded) {\r\n        initExpandedKeys()\r\n      }\r\n      updateFlatTree()\r\n      if (regenerateState.resetChecked) {\r\n        initNodeChecked()\r\n      }\r\n      if (regenerateState.needEmit) {\r\n        nextTick(() => {\r\n          emit('node-generated')\r\n        })\r\n      }\r\n      regenerateState.needEmit = false\r\n      regenerateState.resetExpanded = false\r\n      regenerateState.resetChecked = false\r\n      regenerateTimer = null\r\n    }, 5)\r\n  }\r\n\r\n  // 初始化\r\n  regenerateFlatTree()\r\n\r\n  // 组件卸载时清理定时器\r\n  onUnmounted(() => {\r\n    if (regenerateTimer) {\r\n      clearTimeout(regenerateTimer)\r\n      regenerateTimer = null\r\n    }\r\n  })\r\n\r\n  return {\r\n    flatTree,\r\n    visibleNodes,\r\n    expandedKeys,\r\n    checkedKeys,\r\n    rawData,\r\n    getNodeData,\r\n    getFlatNode,\r\n    regenerateFlatTree,\r\n    flattenTree,\r\n    insertFlatTree,\r\n    halfCheckedKeys,\r\n    selectedKey,\r\n    currentNode,\r\n    toggleNodeChecked,\r\n    setCurrentNode: setSelectionCurrentNode,\r\n    getCheckedNodes,\r\n    getCheckedKeys,\r\n    setCheckedNodes,\r\n    setCheckedKeys,\r\n    expandNode,\r\n    collapseNode,\r\n    dragState,\r\n    filter\r\n  }\r\n}\r\n\r\n","<template>\n  <div class=\"vue-virtual-tree\" :style=\"{ height: typeof height === 'number' ? `${height}px` : height }\"\n    @click=\"handleTreeClick\">\n    <template v-if=\"loading\">\n      <slot name=\"tree-loading\">\n        <div v-if=\"loading\" class=\"vue-virtual-tree__loading\">\n          <!-- 默认loading -->\n          <span class=\"vue-virtual-tree-loading-text\">加载中...</span>\n        </div>\n      </slot>\n    </template>\n    <template v-else>\n      <DynamicScroller ref=\"dynamicScrollerRef\" v-if=\"data.length > 0\" :items=\"visibleNodes\"\n        :min-item-size=\"itemSize || 32\" class=\"vue-virtual-tree__scroller\">\n        <template #default=\"{ item, index, active }\">\n        <DynamicScrollerItem \n          :item=\"item\" \n          :active=\"active\" \n          :data-index=\"index\" \n          :size-dependencies=\"getNodeSizeDependencies(item)\"\n          class=\"vue-virtual-tree__item\">\n          <TreeNode :node=\"item\" :key=\"item.id\" :props=\"props.props\" :show-checkbox=\"showCheckbox\"\n            :expand-on-click-node=\"expandOnClickNode\" :draggable=\"draggable\" :indent=\"props.indent\"\n            :current-key=\"selectedKey\"\n            :drop-type=\"dragState.dropNode?.value?.id === item.id ? dragState.dropType?.value ?? null : null\"\n            @drag-start=\"handleDragStart\" @drag-enter=\"handleDragEnter\" @drag-leave=\"handleDragLeave\"\n            @drag-over=\"handleDragOver\" @drag-end=\"handleDragEnd\" @drop=\"handleDrop\">\n            <template #default=\"{ node, data }\">\n              <slot :node=\"node\" :data=\"data\" />\n            </template>\n            <template #loading=\"{ node, data }\">\n              <slot name=\"loading\" :node=\"node\" :data=\"data\">\n                <!-- 默认loading图标 -->\n                <svg class=\"vue-virtual-tree-node__loading-icon\" viewBox=\"0 0 24 24\" width=\"16\" height=\"16\">\n                  <g transform=\"translate(12,12)\">\n                    <!-- 轨道圆环 -->\n                    <circle cx=\"0\" cy=\"0\" r=\"8\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1\" opacity=\"0.2\" />\n                    <!-- 旋转的3个点 -->\n                    <g class=\"vue-virtual-tree-loading-dots\">\n                      <circle cx=\"0\" cy=\"-8\" r=\"2\" fill=\"currentColor\" />\n                      <circle cx=\"6.928\" cy=\"-4\" r=\"2\" fill=\"currentColor\" opacity=\"0.7\" />\n                      <circle cx=\"6.928\" cy=\"4\" r=\"2\" fill=\"currentColor\" opacity=\"0.4\" />\n                    </g>\n                  </g>\n                </svg>\n              </slot>\n            </template>\n            <template #icon=\"{ node, data }\">\n              <slot name=\"icon\" :node=\"node\" :data=\"data\">\n                <!-- 默认图标 -->\n                <span class=\"default-icon\">\n                  <svg v-if=\"!node.isLeaf\" viewBox=\"0 0 1024 1024\" width=\"16\" height=\"16\">\n                    <path d=\"M384 384l256 256-256 256z\" fill=\"currentColor\" />\n                  </svg>\n                </span>\n              </slot>\n            </template>\n          </TreeNode>\n        </DynamicScrollerItem>\n        </template>\n      </DynamicScroller>\n      <div v-else class=\"vue-virtual-tree__empty\">\n        <slot name=\"empty\">\n          <span>暂无数据</span>\n        </slot>\n      </div>\n    </template>\n  </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { nextTick, ref } from 'vue'\nimport { DynamicScroller, DynamicScrollerItem } from 'vue-virtual-scroller'\nimport TreeNode from './TreeNode.vue'\nimport type { VirtualTreeProps, VirtualTreeEmits, VirtualTreeMethods, FlatTreeNode, TreeNodeData, TreeNodeInstance } from '../types'\nimport { useTreeData } from '../composables/useTreeData'\nimport { getNodeId, findNodeByKey, getNodeChildren, isLeafNode, getNodeLabel } from '../utils/tree'\n\n\ndefineOptions({\n  name: 'VirtualTree'\n})\n\nconst props = withDefaults(defineProps<VirtualTreeProps>(), {\n  data: () => [],\n  props: () => ({}),\n  showCheckbox: false,\n  checkStrictly: false,\n  defaultExpandAll: false,\n  defaultExpandedKeys: () => [],\n  defaultCheckedKeys: () => [],\n  expandOnClickNode: true,\n  lazy: false,\n  accordion: false,\n  draggable: false,\n  itemSize: 32,\n  height: '100%',\n  indent: 18,\n  loading: false\n})\n\nconst emit = defineEmits<VirtualTreeEmits>()\n\n// 数据扁平化\nconst {\n  visibleNodes,\n  rawData,\n  getNodeData,\n  getFlatNode,\n  regenerateFlatTree,\n  insertFlatTree,\n  checkedKeys,\n  halfCheckedKeys,\n  selectedKey,\n  currentNode,\n  toggleNodeChecked,\n  setCurrentNode: setSelectionCurrentNode,\n  getCheckedNodes,\n  getCheckedKeys,\n  setCheckedNodes,\n  setCheckedKeys,\n  expandNode,\n  collapseNode,\n  dragState,\n  filter: filterNodes,\n} = useTreeData(props, emit)\n\nconst dynamicScrollerRef = ref<InstanceType<typeof DynamicScroller> | null>(null)\n\n// 计算节点高度依赖项，用于 DynamicScroller 重新计算高度\nconst getNodeSizeDependencies = (item: FlatTreeNode) => {\n  // 包含所有可能影响节点高度的状态和数据\n  return [\n    item.data,\n    item.isExpanded,\n    item.isChecked,\n    item.isLoading,\n    item.isDisabled,\n    item.level,\n    // 如果节点数据中有 label，也包含进来，因为长文本可能换行\n    getNodeLabel(item.data, props.props)\n  ]\n}\n\n// 事件委托：从事件目标查找节点\nconst getNodeFromEvent = (event: Event): FlatTreeNode | null => {\n  const target = event.target as HTMLElement\n  if (!target) return null\n\n  // 查找最近的带有 data-node-id 属性的元素\n  const nodeElement = target.closest('[data-node-id]')\n  if (!nodeElement) return null\n\n  const nodeId = nodeElement.getAttribute('data-node-id')\n  if (!nodeId) return null\n  // 尝试解析为 number 或 string\n  const id = isNaN(Number(nodeId)) ? nodeId : Number(nodeId)\n  return getFlatNode(id)\n}\n\n// 事件委托：树容器点击事件（只代理 click 事件）\nconst handleTreeClick = (event: MouseEvent) => {\n  const node = getNodeFromEvent(event)\n  if (!node) return\n\n  const target = event.target as HTMLElement\n  if (!target) return\n\n  // 检查点击的是哪个区域\n  const expandIcon = target.closest('.vue-virtual-tree-node__expand-icon')\n  const checkbox = target.closest('.vue-virtual-tree-node__checkbox')\n  const content = target.closest('.vue-virtual-tree-node__content')\n\n  if (checkbox) {\n    // 点击复选框\n    handleNodeCheck(node)\n  } else if (expandIcon) {\n    // 点击展开图标\n    if (node.isExpanded) {\n      handleNodeCollapse(node)\n    } else {\n      handleNodeExpand(node)\n    }\n  } else if (content) {\n    // 点击节点内容\n    handleNodeClick(node, event)\n    if (props.expandOnClickNode && !isLeafNode(node.data, props.props)) {\n      if (node.isExpanded) {\n        handleNodeCollapse(node)\n      } else {\n        handleNodeExpand(node)\n      }\n    }\n  }\n}\n\n// 节点点击\nconst handleNodeClick = (node: FlatTreeNode, event: MouseEvent) => {\n  if (node.isDisabled) return\n\n  // 设置当前选中节点\n  setSelectionCurrentNode(node.id, node.data)\n  emit('current-change', node.data, createNodeInstance(node))\n\n  emit('node-click', node.data, createNodeInstance(node), event)\n}\n\n// 节点展开\nconst handleNodeExpand = async (node: FlatTreeNode) => {\n  if (node.isDisabled) return\n\n  // 懒加载\n  if (props.lazy && !node.isLoaded && props.load) {\n    // 设置loading状态到缓存和节点\n    node.isLoading = true\n    node.isLoaded = false\n    function resolveCallback() {\n      node.isLoading = false\n      node.isLoaded = true\n    }\n    try {\n      await new Promise<void>((resolve) => {\n        props.load!(node.data, (children: TreeNodeData[]) => {\n          // 更新节点的子节点\n          if (children && children.length > 0) {\n            insertFlatTree(node, children);\n          }\n          resolveCallback()\n          resolve()\n        })\n      })\n    } catch (error) {\n      resolveCallback();\n      console.error('Lazy load error:', error)\n    }\n  }\n  expandNode(node)\n  emit('node-expand', node.data, createNodeInstance(node))\n}\n\n// 节点折叠\nconst handleNodeCollapse = (node: FlatTreeNode) => {\n  if (node.isDisabled) return\n  collapseNode(node)\n  emit('node-collapse', node.data, createNodeInstance(node))\n}\n\n// 节点复选框点击\nconst handleNodeCheck = (node: FlatTreeNode) => {\n  if (node.isDisabled) return\n  toggleNodeChecked(node.id)\n\n  const checkedNodes = getCheckedNodes()\n  const checkedKeysArray = getCheckedKeys()\n  const halfCheckedNodes = getCheckedNodes(false, true).filter(n => {\n    const key = getNodeId(n, props.props)\n    return halfCheckedKeys.value.has(key) && !checkedKeys.value.has(key)\n  })\n  const halfCheckedKeysArray = Array.from(halfCheckedKeys.value).filter(\n    key => !checkedKeys.value.has(key)\n  )\n\n  emit('node-check', node.data, {\n    checkedKeys: checkedKeysArray,\n    checkedNodes,\n    halfCheckedKeys: halfCheckedKeysArray,\n    halfCheckedNodes\n  })\n}\n\n// 拖拽开始\nconst handleDragStart = (node: FlatTreeNode, event: DragEvent) => {\n  dragState.handleDragStart(node, event)\n  emit('node-drag-start', node.data, event)\n}\n\n// 拖拽进入\nconst handleDragEnter = (node: FlatTreeNode, event: DragEvent) => {\n  dragState.handleDragEnter(node, event)\n  if (dragState.dropNode?.value?.id === node.id && dragState.draggingNode?.value) {\n    emit('node-drag-enter', dragState.draggingNode.value.data, event, node.data)\n  }\n}\n\n// 拖拽离开\nconst handleDragLeave = (node: FlatTreeNode, event: DragEvent) => {\n  dragState.handleDragLeave(node, event)\n  if (dragState.draggingNode?.value) {\n    emit('node-drag-leave', dragState.draggingNode.value.data, event, node.data)\n  }\n}\n\n// 拖拽悬停\nconst handleDragOver = (node: FlatTreeNode, event: DragEvent) => {\n  dragState.handleDragOver(node, event)\n  if (dragState.dropNode?.value?.id === node.id && dragState.draggingNode?.value) {\n    emit('node-drag-over', dragState.draggingNode.value.data, event, node.data)\n  }\n}\n\n// 拖拽结束\nconst handleDragEnd = (node: FlatTreeNode, event: DragEvent) => {\n  if (dragState.draggingNode?.value) {\n    emit('node-drag-end', dragState.draggingNode.value.data, event)\n  }\n  dragState.handleDragEnd(node, event)\n}\n\n// 放置\nconst handleDrop = (node: FlatTreeNode, event: DragEvent) => {\n  const result = dragState.handleDrop(node, event)\n  if (result) {\n    emit('node-drop', result.draggingNode, result.dropNode, result.dropType, event)\n  }\n}\n\n// 节点实例缓存，避免重复创建和循环引用\nconst nodeInstanceCache = new WeakMap<FlatTreeNode, TreeNodeInstance>()\n\n// 创建节点实例\nconst createNodeInstance = (flatNode: FlatTreeNode): TreeNodeInstance => {\n  // 如果已经缓存，直接返回\n  if (nodeInstanceCache.has(flatNode)) {\n    return nodeInstanceCache.get(flatNode)!\n  }\n\n  // 延迟计算 parent 和 children，避免循环引用\n  let parentInstance: TreeNodeInstance | null = null\n  let childrenInstances: TreeNodeInstance[] | null = null\n\n  const getParent = (): TreeNodeInstance | null => {\n    if (parentInstance !== null) return parentInstance\n    if (flatNode.parentId === null) {\n      parentInstance = null\n      return null\n    }\n    const parent = getFlatNode(flatNode.parentId)\n    if (!parent) {\n      parentInstance = null\n      return null\n    }\n    parentInstance = createNodeInstance(parent)\n    return parentInstance\n  }\n\n  const getChildren = (): TreeNodeInstance[] => {\n    if (childrenInstances !== null) return childrenInstances\n    const children = visibleNodes.value.filter(n => n.parentId === flatNode.id)\n    childrenInstances = children.map(child => createNodeInstance(child))\n    return childrenInstances\n  }\n\n  const getSiblings = (): TreeNodeInstance[] => {\n    const siblings = visibleNodes.value.filter(\n      n => n.parentId === flatNode.parentId && n.id !== flatNode.id\n    )\n    return siblings.map(sibling => createNodeInstance(sibling))\n  }\n\n  const getAllChildren = (): TreeNodeInstance[] => {\n    const result: TreeNodeInstance[] = []\n    const visited = new Set<string | number>()\n    const traverse = (parentId: string | number) => {\n      const children = visibleNodes.value.filter(n => n.parentId === parentId)\n      children.forEach(child => {\n        if (visited.has(child.id)) return // 防止循环引用\n        visited.add(child.id)\n        result.push(createNodeInstance(child))\n        traverse(child.id)\n      })\n    }\n    traverse(flatNode.id)\n    return result\n  }\n\n  const getAllParents = (): TreeNodeInstance[] => {\n    const result: TreeNodeInstance[] = []\n    const visited = new Set<string | number>()\n    let currentId: string | number | null = flatNode.parentId\n    while (currentId !== null) {\n      if (visited.has(currentId)) break // 防止循环引用\n      visited.add(currentId)\n      const parent = getFlatNode(currentId)\n      if (parent) {\n        result.push(createNodeInstance(parent))\n        currentId = parent.parentId\n      } else {\n        break\n      }\n    }\n    return result\n  }\n\n  const instance: TreeNodeInstance = {\n    data: flatNode.data,\n    key: flatNode.id,\n    level: flatNode.level,\n    get parent() {\n      return getParent()\n    },\n    get children() {\n      return getChildren()\n    },\n    expanded: flatNode.isExpanded,\n    checked: flatNode.isChecked || false,\n    disabled: flatNode.isDisabled || false,\n    isLeaf: isLeafNode(flatNode.data, props.props),\n    getLabel: () => getNodeLabel(flatNode.data, props.props),\n    getData: () => flatNode.data,\n    getParent,\n    getChildren,\n    getSiblings,\n    getAllChildren,\n    getAllParents\n  }\n\n  // 缓存实例\n  nodeInstanceCache.set(flatNode, instance)\n  return instance\n}\n\n// 根据 key 获取节点实例\nconst getNode = (key: string | number): TreeNodeInstance | null => {\n  const flatNode = getFlatNode(key)\n  return flatNode ? createNodeInstance(flatNode) : null\n}\n\n\n// 暴露的方法\nconst methods: VirtualTreeMethods = {\n  getCheckedNodes: (leafOnly?: boolean, includeHalfChecked?: boolean) => {\n    return getCheckedNodes(leafOnly, includeHalfChecked)\n  },\n  getCheckedKeys: (leafOnly?: boolean) => {\n    return getCheckedKeys(leafOnly)\n  },\n  setCheckedNodes: (nodes: TreeNodeData[], leafOnly?: boolean) => {\n    setCheckedNodes(nodes, leafOnly)\n  },\n  setCheckedKeys: (keys: (string | number)[], leafOnly?: boolean) => {\n    setCheckedKeys(keys, leafOnly)\n  },\n  getCurrentNode: () => {\n    return currentNode.value\n  },\n  setCurrentNode: (node: TreeNodeData | string | number) => {\n    if (typeof node === 'string' || typeof node === 'number') {\n      const nodeData = getNodeData(node)\n      setSelectionCurrentNode(node, nodeData)\n    } else {\n      const key = getNodeId(node, props.props)\n      setSelectionCurrentNode(key, node)\n    }\n  },\n  getCurrentKey: () => {\n    return selectedKey.value\n  },\n  setCurrentKey: (key: string | number) => {\n    setSelectionCurrentNode(key, getNodeData(key))\n  },\n  filter: (value: string) => {\n    return filterNodes(value).then(() => {\n      nextTick(() => {\n        dynamicScrollerRef.value?.scrollToItem(0);\n        dynamicScrollerRef.value?.forceUpdate();\n      })\n    })\n  },\n  getNode: (key: string | number) => {\n    return getNode(key)\n  },\n  remove: (key: string | number) => {\n    const node = findNodeByKey(rawData.value, key, props.props)\n    if (!node) return\n\n    // 从原始数据中删除节点\n    const removeFromArray = (arr: TreeNodeData[], targetKey: string | number): boolean => {\n      for (let i = 0; i < arr.length; i++) {\n        if (getNodeId(arr[i], props.props) === targetKey) {\n          arr.splice(i, 1)\n          return true\n        }\n        const children = getNodeChildren(arr[i], props.props)\n        if (children.length > 0 && removeFromArray(children, targetKey)) {\n          return true\n        }\n      }\n      return false\n    }\n\n    removeFromArray(rawData.value, key)\n    regenerateFlatTree()\n  },\n  append: (data: TreeNodeData, parentKey?: string | number) => {\n    if (parentKey === undefined) {\n      rawData.value.push(data)\n    } else {\n      const parent = findNodeByKey(rawData.value, parentKey, props.props)\n      if (parent) {\n        const config = props.props || {}\n        const childrenKey = config.children || 'children'\n        if (!parent[childrenKey]) {\n          parent[childrenKey] = []\n        }\n        parent[childrenKey].push(data)\n      }\n    }\n    regenerateFlatTree()\n  },\n  insertBefore: (data: TreeNodeData, key: string | number) => {\n    const insertIntoArray = (arr: TreeNodeData[], targetKey: string | number, newData: TreeNodeData): boolean => {\n      for (let i = 0; i < arr.length; i++) {\n        if (getNodeId(arr[i], props.props) === targetKey) {\n          arr.splice(i, 0, newData)\n          return true\n        }\n        const children = getNodeChildren(arr[i], props.props)\n        if (children.length > 0 && insertIntoArray(children, targetKey, newData)) {\n          return true\n        }\n      }\n      return false\n    }\n\n    insertIntoArray(rawData.value, key, data)\n    regenerateFlatTree()\n  },\n  insertAfter: (data: TreeNodeData, key: string | number) => {\n    const insertIntoArray = (arr: TreeNodeData[], targetKey: string | number, newData: TreeNodeData): boolean => {\n      for (let i = 0; i < arr.length; i++) {\n        if (getNodeId(arr[i], props.props) === targetKey) {\n          arr.splice(i + 1, 0, newData)\n          return true\n        }\n        const children = getNodeChildren(arr[i], props.props)\n        if (children.length > 0 && insertIntoArray(children, targetKey, newData)) {\n          return true\n        }\n      }\n      return false\n    }\n\n    insertIntoArray(rawData.value, key, data)\n    regenerateFlatTree()\n  },\n  updateKeyChildren: (key: string | number, data: TreeNodeData[]) => {\n    const node = findNodeByKey(rawData.value, key, props.props)\n    if (node) {\n      const config = props.props || {}\n      const childrenKey = config.children || 'children'\n      node[childrenKey] = data\n      regenerateFlatTree()\n    }\n  },\n  scrollToNode: (key: string | number | TreeNodeData, options?: { align?: 'top' | 'center' | 'bottom', offset?: number }) => {\n    // 获取节点的 key\n    let targetKey: string | number\n    if (typeof key === 'string' || typeof key === 'number') {\n      targetKey = key\n    } else {\n      targetKey = getNodeId(key, props.props)\n    }\n\n    // 查找对应的 FlatTreeNode\n    const flatNode = getFlatNode(targetKey)\n    if (!flatNode) {\n      console.warn(`[VirtualTree] Node with key \"${targetKey}\" not found`)\n      return\n    }\n\n    // 如果节点不在可见列表中，需要展开所有父节点\n    const ensureNodeVisible = async (node: FlatTreeNode) => {\n      if (node.parentId !== null) {\n        const parent = getFlatNode(node.parentId)\n        if (parent && !parent.isExpanded) {\n          // 展开父节点\n          await handleNodeExpand(parent)\n          // 等待 DOM 更新\n          await nextTick()\n          // 递归确保所有父节点都展开\n          await ensureNodeVisible(parent)\n        }\n      }\n    }\n\n    // 执行滚动\n    const performScroll = async () => {\n      // 确保节点可见\n      await ensureNodeVisible(flatNode)\n      \n      // 等待 DOM 更新完成\n      await nextTick()\n      \n      // 查找节点在 visibleNodes 中的索引\n      const index = visibleNodes.value.findIndex(node => node.id === targetKey)\n      if (index === -1) {\n        console.warn(`[VirtualTree] Node with key \"${targetKey}\" is not visible`)\n        return\n      }\n\n      // 调用 DynamicScroller 的 scrollToItem 方法\n      if (dynamicScrollerRef.value) {\n        const align = options?.align || 'top'\n        const offset = options?.offset || 0\n        \n        // DynamicScroller 的 scrollToItem 方法签名: scrollToItem(index, align?, offset?)\n        // align: 'start' | 'center' | 'end'\n        const alignMap: Record<'top' | 'center' | 'bottom', 'start' | 'center' | 'end'> = {\n          top: 'start',\n          center: 'center',\n          bottom: 'end'\n        }\n        \n        const scroller = dynamicScrollerRef.value\n        if (scroller && typeof scroller.scrollToItem === 'function') {\n          if (offset !== 0) {\n            // 如果提供了 offset，使用三个参数\n            scroller.scrollToItem(index, alignMap[align], offset)\n          } else if (align !== 'top') {\n            // 如果提供了 align，使用两个参数\n            scroller.scrollToItem(index, alignMap[align])\n          } else {\n            // 只使用 index\n            scroller.scrollToItem(index)\n          }\n        }\n        \n        // 强制更新以确保滚动生效\n        if (typeof scroller.forceUpdate === 'function') {\n          scroller.forceUpdate()\n        }\n      }\n    }\n\n    performScroll()\n  },\n  nodeGenerated: () => {\n    emit('node-generated')\n  }\n}\n\n// 暴露方法给父组件\ndefineExpose(methods)\n</script>\n\n<style scoped lang=\"scss\">\n.vue-virtual-tree {\n  width: 100%;\n  height: 100%;\n  overflow: hidden;\n  font-size: 14px;\n  color: #606266;\n\n  &__scroller {\n    height: 100%;\n  }\n\n  &__item {\n    width: 100%;\n  }\n}\n\n.vue-virtual-tree__empty {\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  height: 100%;\n  color: #909399;\n  font-size: 14px;\n}\n\n.vue-virtual-tree__loading {\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  height: 100%;\n  color: #909399;\n}\n\n.vue-virtual-tree-loading-arc {\n  animation: vue-virtual-tree-loading-rotate 1s linear infinite;\n  transform-origin: center;\n}\n\n.vue-virtual-tree-loading-text {\n  font-size: 14px;\n  color: #909399;\n}\n\n.vue-virtual-tree-node {\n  &.is-expanded .vue-virtual-tree-node__expand-icon .default-icon {\n    transform: rotate(90deg);\n  }\n\n  &.is-loading {\n    .vue-virtual-tree-node__expand-icon {\n      color: #409eff;\n    }\n  }\n\n  &__loading-icon {\n    animation: vue-virtual-tree-loading-rotate 1.5s linear infinite;\n  }\n\n  &__loading-dots {\n    animation: vue-virtual-tree-loading-dots-rotate 1.5s linear infinite;\n  }\n\n  @keyframes vue-virtual-tree-loading-rotate {\n    0% {\n      transform: rotate(0deg);\n    }\n\n    100% {\n      transform: rotate(360deg);\n    }\n  }\n\n  @keyframes vue-virtual-tree-loading-dots-rotate {\n    0% {\n      transform: rotate(0deg);\n    }\n\n    100% {\n      transform: rotate(360deg);\n    }\n  }\n}\n</style>\n","import VirtualTree from './components/VirtualTree.vue'\r\nimport type { App } from 'vue'\r\nimport type { VirtualTreeProps, VirtualTreeEmits, VirtualTreeMethods } from './types'\r\n\r\nexport { VirtualTree }\r\nexport type { VirtualTreeProps, VirtualTreeEmits, VirtualTreeMethods }\r\nexport type { TreeNodeData, FlatTreeNode, TreePropsConfig, TreeNodeInstance } from './types'\r\n\r\nexport default {\r\n  install(app: App) {\r\n    app.component('VirtualTree', VirtualTree)\r\n  }\r\n}\r\n\r\n"],"names":["DEFAULT_PROPS","getNodeId","node","props","config","getNodeLabel","getNodeChildren","isNodeDisabled","isLeafNode","traverseTree","nodes","callback","parent","children","findNode","predicate","found","findNodeByKey","key","getAllKeys","keys","__props","emit","__emit","isDragging","ref","label","computed","isLeaf","isCurrent","indent","indentProp","handleDragStart","event","handleDragEnter","handleDragLeave","handleDragOver","handleDragEnd","handleDrop","useTreeSelection","flatTree","getNodeData","getFlatNode","checkedKeys","halfCheckedKeys","selectedKey","currentNode","initNodeChecked","setNodeChecked","initCurrentNode","getAllChildrenKeys","nodeId","nodeData","traverse","data","child","childId","updateHalfCheckedKeys","allKeys","n","childrenKeys","checkedChildren","k","setNodeCheckedInTree","checked","setChildrenChecked","parentNode","checkedState","updateParentChecked","childNode","parentId","siblings","checkedCount","indeterminateCount","checkStrictly","toggleNodeChecked","isChecked","setCurrentNode","getCheckedNodes","leafOnly","includeHalfChecked","getCheckedKeys","setCheckedNodes","setCheckedKeys","watch","newKey","useTreeExpand","visibleNodes","refreshVisibleIndexes","expandedKeys","initExpandedKeys","collectVisibleDescendants","result","expandVisibleNode","descendants","collapseVisibleNode","expandNode","sibling","setRecursionExpanded","isExpanded","collapseNode","mergeSort","mid","left","right","merge","i","j","useTreeFilter","flatNodeMap","filteredFlatTree","filteredFlatNodeMap","isFiltered","setVisibleNodes","rebuildVisibleNodes","roots","root","defaultFilterMethod","value","cloneNode","filterText","filter","resolve","filterMethod","clonedNodes","clonedNode","sortedNodes","useTreeDrag","draggingNode","dropNode","dropType","defaultAllowDrag","_node","defaultAllowDrop","type","draggingId","isDescendant","draggingData","dropData","rect","y","height","threshold","dragging","dropping","relatedTarget","_a","newDropType","_event","finalDropType","useTreeData","rawData","treeDataWrapper","treeDataMapWrapper","index","id","flatNode","setSelectionCurrentNode","dragState","flattenTree","level","startIndex","visible","map","visibleList","genenrateFlatNodes","container","length","childNodes","updatePending","updateFlatTree","flatNodes","nodeMap","visibleNodesResult","insertFlatTree","regenerateState","newData","regenerateFlatTree","regenerateTimer","nextTick","onUnmounted","filterNodes","dynamicScrollerRef","getNodeSizeDependencies","item","getNodeFromEvent","target","nodeElement","handleTreeClick","expandIcon","checkbox","content","handleNodeCheck","handleNodeCollapse","handleNodeExpand","handleNodeClick","createNodeInstance","resolveCallback","error","checkedNodes","checkedKeysArray","halfCheckedNodes","halfCheckedKeysArray","_b","_c","nodeInstanceCache","parentInstance","childrenInstances","getParent","getChildren","getSiblings","getAllChildren","visited","getAllParents","currentId","instance","getNode","__expose","removeFromArray","arr","targetKey","parentKey","childrenKey","insertIntoArray","options","ensureNodeVisible","align","offset","alignMap","scroller","app","VirtualTree"],"mappings":"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"}