瀏覽代碼

fix: 修改图层树折叠问题,控件图标问题

jiaxing.liao 5 天之前
父節點
當前提交
d0e03623f0

+ 57 - 1
src/renderer/src/views/designer/sidebar/Hierarchy.vue

@@ -9,18 +9,20 @@
         <el-tree
           ref="hierarchyTreeRef"
           style="max-width: 600px"
-          default-expand-all
           node-key="id"
           draggable
           :allow-drag="allowDrag"
           :allow-drop="allowDrop"
           :height="treeHeight"
+          :default-expanded-keys="expandedNodeKeys"
           :highlight-current="false"
           :data="hierarchyTreeData"
           :props="{ label: 'name', children: 'children' }"
           :filter-node-method="filterNode"
           @node-click="handleNodeClick"
           @node-drop="handleNodeDrop"
+          @node-expand="handleNodeExpand"
+          @node-collapse="handleNodeCollapse"
         >
           <template #default="{ node, data }">
             <ScreenTreeItem
@@ -71,6 +73,8 @@ const projectStore = useProjectStore()
 const search = ref('')
 const hierarchyTreeRef = ref<TreeInstance | null>(null)
 const treeBoxRef = ref<HTMLDivElement | null>(null)
+const expandedNodeKeySet = ref(new Set<string>())
+const hasInitializedExpandedKeys = ref(false)
 
 const { height } = useElementSize(treeBoxRef, {
   height: 100,
@@ -125,6 +129,58 @@ const hierarchyTreeData = computed<HierarchyNodeData[]>(() => {
   )
 })
 
+const collectNodeKeys = (nodes: HierarchyNodeData[]) => {
+  const keys: string[] = []
+
+  const walk = (items: HierarchyNodeData[]) => {
+    items.forEach((item) => {
+      keys.push(item.id)
+      walk(item.children || [])
+    })
+  }
+
+  walk(nodes)
+
+  return keys
+}
+
+const collectCurrentAndDescendantNodeKeys = (node: HierarchyNodeData) => {
+  return collectNodeKeys([node])
+}
+
+const expandedNodeKeys = computed(() => [...expandedNodeKeySet.value])
+
+watch(
+  hierarchyTreeData,
+  (nodes) => {
+    const nodeKeys = collectNodeKeys(nodes)
+
+    if (!hasInitializedExpandedKeys.value) {
+      expandedNodeKeySet.value = new Set(nodeKeys)
+      hasInitializedExpandedKeys.value = true
+      return
+    }
+
+    const existingKeys = new Set(nodeKeys)
+    expandedNodeKeySet.value = new Set(
+      [...expandedNodeKeySet.value].filter((key) => existingKeys.has(key))
+    )
+  },
+  {
+    immediate: true
+  }
+)
+
+const handleNodeExpand = (nodeData: HierarchyNodeData) => {
+  expandedNodeKeySet.value = new Set(expandedNodeKeySet.value).add(nodeData.id)
+}
+
+const handleNodeCollapse = (nodeData: HierarchyNodeData) => {
+  const next = new Set(expandedNodeKeySet.value)
+  collectCurrentAndDescendantNodeKeys(nodeData).forEach((key) => next.delete(key))
+  expandedNodeKeySet.value = next
+}
+
 const setOpenedPage = (screenId?: string, pageId?: string) => {
   if (!screenId || !pageId) return
 

+ 13 - 0
src/renderer/src/views/designer/sidebar/components/PageTreeItem.vue

@@ -7,6 +7,13 @@
   >
     <div class="flex-1 flex items-center gap-8px">
       <LuPanelsTopLeft size="14px" v-if="data.type === 'page'" />
+      <!-- 展示控件图标 -->
+      <img
+        v-else-if="widgetIcon"
+        class="w-14px h-14px object-contain shrink-0"
+        :src="widgetIcon"
+        draggable="false"
+      />
       <LuBox size="14px" v-else />
       <span>{{ data.name }}</span>
     </div>
@@ -53,6 +60,7 @@ import {
 } from 'vue-icons-plus/lu'
 import { useProjectStore } from '@/store/modules/project'
 import { useActionStore } from '@/store/modules/action'
+import componentMap from '@/lvgl-widgets'
 
 const props = defineProps<{
   node: RenderContentContext['node']
@@ -62,6 +70,11 @@ const props = defineProps<{
 const projectStore = useProjectStore()
 const actionStore = useActionStore()
 
+const widgetIcon = computed(() => {
+  if (props.data.type === 'page') return ''
+  return componentMap[props.data.type]?.icon || ''
+})
+
 const isBind = computed(() => {
   return actionStore.isWidgetBoundById(props.data.id)
 })