瀏覽代碼

改为懒加载树

duy 1 月之前
父節點
當前提交
8a0bd92123
共有 1 個文件被更改,包括 93 次插入67 次删除
  1. 93 67
      src/views/data-fill/components/linkData.vue

+ 93 - 67
src/views/data-fill/components/linkData.vue

@@ -26,8 +26,11 @@
                             ref="treeRef"
                             :data="treeData"
                             :props="treeProps"
-                            :default-expand-all="true"
+                            :default-expand-all="false"
+                        
                             :filter-node-method="filterNode"
+                            :load="loadNode"  
+                            lazy  
                             node-key="id"
                             check-strictly
                             @node-click="handleNodeClick"
@@ -83,71 +86,88 @@ const queryValue = ref('')
 // 树形组件引用
 const treeRef = ref(null)
 
-// 选中的节点ID(改为单个值,而非数组)
-const selectedNode = ref('')
+// 选中的节点ID
+const selectedNodeId = ref(null)
 
 // 树形结构配置
 const treeProps = {
     label: 'name',
     children: 'children',
+    isLeaf: 'isLeaf', // 新增isLeaf字段判断是否为叶子节点
 }
 
-// 树形数据 - 模拟数据
-const treeData = ref([
-    {
-        id: 1,
-        name: '路基工程',
-        children: [
-            { id: 11, name: 'K54+467.791~K54+707.3 路基工程' },
-        ],
-    },
-    {
-        id: 2,
-        name: '涵洞通道',
-        children: [
-            { id: 21, name: 'K54+469~K54+721.5 涵洞通道' },
-        ],
-    },
-    {
-        id: 3,
-        name: '人字预制装配护坡',
-        children: [
-            { id: 31, name: '人字预制装配护坡' },
-            { id: 32, name: '人字预制装配护坡 (右侧)' },
-        ],
-    },
-    {
-        id: 4,
-        name: '路肩墙',
-        children: [
-            { id: 41, name: '路肩墙' },
-            { id: 42, name: '人字预制装配护坡 (右侧)' },
-        ],
-    },
-    {
-        id: 5,
-        name: '其他工程',
-        children: [
-            { id: 51, name: '喷射植草' },
-            { id: 52, name: '人字预制装配护坡 (右侧)' },
-        ],
-    },
-])
+// 树形数据 - 初始只存放根节点
+const treeData = ref([])
 
 // 监听对话框显示状态
 watch(() => linkModal.value, (val) => {
     if (val) {
         // 对话框打开时的初始化操作
-        selectedNode.value = ''
+        selectedNodeId.value = ''
         queryValue.value = ''
-        loadTreeDataByWorkArea(leftRadio.value)
+        loadRootNodes(leftRadio.value) // 加载根节点
     }
 })
 
-// 根据工区加载树形数据
-const loadTreeDataByWorkArea = (workArea) => {
-    console.log(`加载${workArea}对应的树形数据`)
-    // 实际项目中这里应该是接口请求
+// 加载根节点数据
+const loadRootNodes = (workArea) => {
+    console.log(`加载${workArea}的根节点数据`)
+    // 实际项目中这里应该是接口请求根节点
+    // 模拟根节点数据
+    treeData.value = [
+        { id: 1, name: '路基工程', isLeaf: false },
+        { id: 2, name: '涵洞通道', isLeaf: false },
+        { id: 3, name: '人字预制装配护坡', isLeaf: false },
+        { id: 4, name: '路肩墙', isLeaf: false },
+        { id: 5, name: '其他工程', isLeaf: false },
+    ]
+}
+
+// 懒加载节点方法
+const loadNode = (node, resolve) => {
+    // node为当前点击的节点,resolve用于返回子节点数据
+    if (node.level === 0) {
+        // 根节点已经在treeData中定义,不需要额外加载
+        return resolve([])
+    }
+    
+    console.log(`加载节点${node.data.id}的子节点`)
+    
+    // 实际项目中这里应该是接口请求,根据node.data.id获取子节点
+    // 模拟异步加载子节点
+    setTimeout(() => {
+        // 模拟不同节点的子节点数据
+        let children = []
+        switch (node.data.id) {
+            case 1:
+                children = [{ id: 11, name: 'K54+467.791~K54+707.3 路基工程', isLeaf: true }]
+                break
+            case 2:
+                children = [{ id: 21, name: 'K54+469~K54+721.5 涵洞通道', isLeaf: true }]
+                break
+            case 3:
+                children = [
+                    { id: 31, name: '人字预制装配护坡', isLeaf: true },
+                    { id: 32, name: '人字预制装配护坡 (右侧)', isLeaf: true },
+                ]
+                break
+            case 4:
+                children = [
+                    { id: 41, name: '路肩墙', isLeaf: true },
+                    { id: 42, name: '人字预制装配护坡 (右侧)', isLeaf: true },
+                ]
+                break
+            case 5:
+                children = [
+                    { id: 51, name: '喷射植草', isLeaf: true },
+                    { id: 52, name: '人字预制装配护坡 (右侧)', isLeaf: true },
+                ]
+                break
+            default:
+                children = []
+        }
+        resolve(children)
+    }, 500) // 模拟网络延迟
 }
 
 // 关闭对话框
@@ -170,41 +190,47 @@ const filterNode = (value, data) => {
 // 处理节点点击事件
 const handleNodeClick = (data) => {
     // 如果是叶子节点才允许选中
-    if (!data.children || data.children.length === 0) {
-        selectedNode.value = data.id
+    if (data.isLeaf) {
+        selectedNodeId.value = data.id
     }
 }
-const selectedNodeId = ref(null)
+
 // 确认关联
 const confirmLink = () => {
-    if (!selectedNode.value) {
+    if (!selectedNodeId.value) {
         // 提示用户未选择节点
         return
     }
     
-    // 找到选中的节点数据
-    const findSelectedNode = (nodes, id) => {
+    // 找到选中的节点数据(实际项目中可能需要根据ID重新请求详情)
+    const findSelectedNode = async (nodes, id) => {
         for (const node of nodes) {
             if (node.id === id) return node
-            if (node.children) {
-                const found = findSelectedNode(node.children, id)
+            if (!node.isLeaf) {
+                // 如果不是叶子节点,尝试加载其子节点再查找
+                // 这里简化处理,实际可能需要更复杂的逻辑
+                const children = await new Promise(resolve => {
+                    loadNode({ data: node }, resolve)
+                })
+                const found = findSelectedNode(children, id)
                 if (found) return found
             }
         }
         return null
     }
     
-    const selectedData = findSelectedNode(treeData.value, selectedNode.value)
-    
-    // 触发保存事件,将选中的数据传递给父组件
-    emit('save', selectedData)
-    closeModal()
+    findSelectedNode(treeData.value, selectedNodeId.value).then(selectedData => {
+        if (selectedData) {
+            emit('save', selectedData)
+            closeModal()
+        }
+    })
 }
 
-// 监听左侧工区变化,重新加载数据
+// 监听左侧工区变化,重新加载根节点数据
 watch(leftRadio, (newVal) => {
-    loadTreeDataByWorkArea(newVal)
-    selectedNode.value = ''
+    loadRootNodes(newVal)
+    selectedNodeId.value = ''
 })
 </script>
 
@@ -218,4 +244,4 @@ watch(leftRadio, (newVal) => {
   display: flex;
   align-items: center;
 }
-</style>
+</style>