From a1d7e81859f554f3a53680cc35f0f49bf1f77098 Mon Sep 17 00:00:00 2001
From: wwf <1971391498@qq.com>
Date: 星期四, 14 五月 2026 14:37:02 +0800
Subject: [PATCH] 导入项目

---
 src/components/DiyEditor/components/ComponentLibrary.vue |  211 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 211 insertions(+), 0 deletions(-)

diff --git a/src/components/DiyEditor/components/ComponentLibrary.vue b/src/components/DiyEditor/components/ComponentLibrary.vue
new file mode 100644
index 0000000..06f2312
--- /dev/null
+++ b/src/components/DiyEditor/components/ComponentLibrary.vue
@@ -0,0 +1,211 @@
+<template>
+  <el-aside class="editor-left" width="261px">
+    <el-scrollbar>
+      <el-collapse v-model="extendGroups">
+        <el-collapse-item
+          v-for="group in groups"
+          :key="group.name"
+          :name="group.name"
+          :title="group.name"
+        >
+          <draggable
+            class="component-container"
+            ghost-class="draggable-ghost"
+            item-key="index"
+            :list="group.components"
+            :sort="false"
+            :group="{ name: 'component', pull: 'clone', put: false }"
+            :clone="handleCloneComponent"
+            :animation="200"
+            :force-fallback="false"
+          >
+            <template #item="{ element }">
+              <div>
+                <div class="drag-placement">缁勪欢鏀剧疆鍖哄煙</div>
+                <div class="component">
+                  <Icon :icon="element.icon" :size="32" />
+                  <span class="mt-4px text-12px">{{ element.name }}</span>
+                </div>
+              </div>
+            </template>
+          </draggable>
+        </el-collapse-item>
+      </el-collapse>
+    </el-scrollbar>
+  </el-aside>
+</template>
+
+<script setup lang="ts">
+import draggable from 'vuedraggable'
+import { componentConfigs } from '../components/mobile/index'
+import { cloneDeep } from 'lodash-es'
+import { DiyComponent, DiyComponentLibrary } from '@/components/DiyEditor/util'
+
+/** 缁勪欢搴擄細鐩墠宸︿晶鐨勩�愬熀纭�缁勪欢銆戙�併�愬浘鏂囩粍浠躲�戦儴鍒� */
+defineOptions({ name: 'ComponentLibrary' })
+
+// 缁勪欢鍒楄〃
+const props = defineProps<{
+  list: DiyComponentLibrary[]
+}>()
+// 缁勪欢鍒嗙粍
+const groups = reactive<any[]>([])
+// 灞曞紑鐨勬姌鍙犻潰鏉�
+const extendGroups = reactive<string[]>([])
+
+// 鐩戝惉 list 灞炴�э紝鎸夌収 DiyComponentLibrary 鐨� name 鍒嗙粍
+watch(
+  () => props.list,
+  () => {
+    // 娓呴櫎鏃ф暟鎹�
+    extendGroups.length = 0
+    groups.length = 0
+    // 閲嶆柊鐢熸垚鏁版嵁
+    props.list.forEach((group) => {
+      // 鏄惁灞曞紑鍒嗙粍
+      if (group.extended) {
+        extendGroups.push(group.name)
+      }
+      // 鏌ユ壘缁勪欢
+      const components = group.components
+        .map((name) => componentConfigs[name] as DiyComponent<any>)
+        .filter((component) => component)
+      if (components.length > 0) {
+        groups.push({
+          name: group.name,
+          components
+        })
+      }
+    })
+  },
+  {
+    immediate: true
+  }
+)
+
+// 鍏嬮殕缁勪欢
+const handleCloneComponent = (component: DiyComponent<any>) => {
+  const instance = cloneDeep(component)
+  instance.uid = new Date().getTime()
+  return instance
+}
+</script>
+
+<style scoped lang="scss">
+.editor-left {
+  z-index: 1;
+  flex-shrink: 0;
+  user-select: none;
+  box-shadow: 8px 0 8px -8px rgb(0 0 0 / 12%);
+
+  :deep(.el-collapse) {
+    border-top: none;
+  }
+
+  :deep(.el-collapse-item__wrap) {
+    border-bottom: none;
+  }
+
+  :deep(.el-collapse-item__content) {
+    padding-bottom: 0;
+  }
+
+  :deep(.el-collapse-item__header) {
+    height: 32px;
+    padding: 0 24px;
+    line-height: 32px;
+    background-color: var(--el-bg-color-page);
+    border-bottom: none;
+  }
+
+  .component-container {
+    display: flex;
+    flex-wrap: wrap;
+    align-items: center;
+  }
+
+  .component {
+    display: flex;
+    width: 86px;
+    height: 86px;
+    cursor: move;
+    border-right: 1px solid var(--el-border-color-lighter);
+    border-bottom: 1px solid var(--el-border-color-lighter);
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+
+    .el-icon {
+      margin-bottom: 4px;
+      color: gray;
+    }
+  }
+
+  .component.active,
+  .component:hover {
+    color: var(--el-color-white);
+    background: var(--el-color-primary);
+
+    .el-icon {
+      color: var(--el-color-white);
+    }
+  }
+
+  .component:nth-of-type(3n) {
+    border-right: none;
+  }
+}
+
+/* 鎷栨嫿鍗犱綅鎻愮ず锛岄粯璁や笉鏄剧ず */
+.drag-placement {
+  display: none;
+  color: #fff;
+}
+
+.drag-area {
+  /* 鎷栨嫿鍒版墜鏈哄尯鍩熸椂鐨勬牱寮� */
+  .draggable-ghost {
+    display: flex;
+    width: 100%;
+    height: 40px;
+
+    /* 鏉$汗鑳屾櫙 */
+    background: linear-gradient(
+      45deg,
+      #91a8d5 0,
+      #91a8d5 10%,
+      #94b4eb 10%,
+      #94b4eb 50%,
+      #91a8d5 50%,
+      #91a8d5 60%,
+      #94b4eb 60%,
+      #94b4eb
+    );
+    background-size: 1rem 1rem;
+    transition: all 0.5s;
+    justify-content: center;
+    align-items: center;
+
+    span {
+      display: inline-block;
+      width: 140px;
+      height: 25px;
+      font-size: 12px;
+      line-height: 25px;
+      color: #fff;
+      text-align: center;
+      background: #5487df;
+    }
+
+    /* 鎷栨嫿鏃堕殣钘忕粍浠� */
+    .component {
+      display: none;
+    }
+
+    /* 鎷栨嫿鏃舵樉绀哄崰浣嶆彁绀� */
+    .drag-placement {
+      display: block;
+    }
+  }
+}
+</style>

--
Gitblit v1.8.0