Prechádzať zdrojové kódy

feat: 添加组件选中与取消

liaojiaxing 10 mesiacov pred
rodič
commit
a4a5ba2ed7

+ 10 - 8
src/components/Text/Title/src/index.vue

@@ -1,20 +1,22 @@
 <template>
-  <div class="cus-title" v-bind="$attrs">
+  <div class="cus-title" :style="style">
     {{ title }}
   </div>
 </template>
 
 <script setup lang="ts">
-import { defineProps } from 'vue';
+import { defineProps, computed } from 'vue';
 import { titleProps } from './props';
 
-defineProps(titleProps);
+const props = defineProps(titleProps);
+const style = computed(() => ({
+  ...props,
+  width: props.width + 'px',
+  height: props.height + 'px',
+  fontSize: props.fontSize + 'px',
+  lineHeight: props.height + 'px',
+}));
 </script>
 
 <style lang="less" scoped>
-.cus-title {
-  font-size: 24px;
-  color: #fff;
-  font-weight: bold;
-}
 </style>

+ 30 - 1
src/components/Text/Title/src/props.ts

@@ -1,12 +1,41 @@
+import { PropType } from 'vue';
+
 export const titleProps = {
   title: {
     type: String,
     required: true
+  },
+  width: {
+    type: Number,
+  },
+  height: {
+    type: Number,
+  },
+  fontSize: {
+    type: Number,
+  },
+  fontWeight: {
+    type: [Number, String],
+  },
+  color: {
+    type: String,
+  },
+  backgroundColor: {
+    type: String,
+  },
+  textAlign: {
+    type: String,
+  },
+  direction: {
+    type: String as PropType<'horizontal' | 'vertical'>,
   }
 }
 
 export const defaultPropsValue = {
   title: '标题',
   width: 300,
-  height: 80
+  height: 80,
+  fontSize: 24,
+  color: '#fff',
+  backgroundColor: 'none',
 }

+ 2 - 2
src/store/modules/project.ts

@@ -111,7 +111,7 @@ export const useProjectStore = defineStore({
         }
       });
 
-      this.selectedElementKeys.push(element.key);
+      this.selectedElementKeys = [element.key];
     },
     // 更新组件
     updateElement(key: number, payload: Record<string, any>) {
@@ -133,7 +133,7 @@ export const useProjectStore = defineStore({
     },
     // 设置选中的元素
     setSelectedElementKeys(keys: number[]) {
-      this.selectedElementKeys.push(...keys);
+      this.selectedElementKeys = keys;
     },
     // 删除选中的元素
     deleteSelectedElement(keys: number[]) {

+ 3 - 0
src/views/designer/component/ComponentLibary.vue

@@ -146,6 +146,9 @@ const handleAddComp = (item: CompItem) => {
 // 2、拖拽到画布区域时通过drop事件完成添加组件
 // 3、清空临时数据
 const handleDragStart = (item: CompItem) => {
+  openDrawer.value = false;
+  selectedKeys.value = [];
+  
   projectStore.setAddCompData({
     key: Date.now(),
     name: item.name,

+ 22 - 16
src/views/designer/component/ComponentWrapper.vue

@@ -4,7 +4,7 @@
     ref="componentWrapperRef"
     :style="warpperStyle"
   >
-    <div class="component-content">
+    <div class="component-content" @click="handleSelectComponent">
       <component :is="component" v-bind="componentData.props" />
     </div>
     <div v-if="showEditBox" class="edit-box" :style="editWapperStyle">
@@ -87,8 +87,15 @@ useDraggable(componentWrapperRef, {
       },
     });
   },
+  onStart: () => {
+    projectStore.setSelectedElementKeys([componentData.key]);
+  }
 });
+const handleSelectComponent = () => {
+  projectStore.setSelectedElementKeys([componentData.key]);
+};
 
+/* ===============================缩放组件==================================== */
 const dragPointList = [
   "top-left",
   "top-center",
@@ -100,7 +107,6 @@ const dragPointList = [
   "bottom-right",
 ];
 
-/* ===============================缩放组件==================================== */
 const startPoint = {
   x: 0,
   y: 0,
@@ -193,55 +199,55 @@ const handleDragEnd = () => {
   position: absolute;
   &-point {
     position: absolute;
-    width: 6px;
-    height: 6px;
+    width: 8px;
+    height: 8px;
     background: #fff;
     border-radius: 50%;
     border: solid 1px @primary-color;
   }
   .top-left {
-    top: -3px;
-    left: -3px;
+    top: -4px;
+    left: -4px;
     cursor: nw-resize;
   }
   .top-center {
-    top: -3px;
+    top: -4px;
     left: 50%;
     transform: translateX(-50%);
     transform-origin: center;
     cursor: n-resize;
   }
   .top-right {
-    top: -3px;
-    right: -3px;
+    top: -4px;
+    right: -4px;
     cursor: ne-resize;
   }
   .left-center {
     top: 50%;
-    left: -3px;
+    left: -4px;
     transform: translateY(-50%);
     cursor: w-resize;
   }
   .right-center {
     top: 50%;
-    right: -3px;
+    right: -4px;
     transform: translateY(-50%);
     cursor: e-resize;
   }
   .bottom-left {
-    bottom: -3px;
-    left: -3px;
+    bottom: -4px;
+    left: -4px;
     cursor: sw-resize;
   }
   .bottom-center {
-    bottom: -3px;
+    bottom: -4px;
     left: 50%;
     transform: translateX(-50%);
     cursor: s-resize;
   }
   .bottom-right {
-    bottom: -3px;
-    right: -3px;
+    bottom: -4px;
+    right: -4px;
     cursor: se-resize;
   }
 }

+ 13 - 0
src/views/designer/component/Stage.vue

@@ -12,6 +12,7 @@
         ondragover="return false"
         :style="getStyles.canvasStyle"
         @drop="handleDrop"
+        @click="handleCanvasClick"
       >
         <ComponentWrapper 
           v-for="item in projectStore.elements" 
@@ -162,6 +163,18 @@ const handleDrop = (e: DragEvent) => {
   }
 };
 
+// 点击画布,处理组件选中状态
+const handleCanvasClick = (e: MouseEvent) => {
+  console.log(e.target)
+  if(
+    !e?.target?.closest(".edit-box") 
+    && !e?.target?.closest(".component-content")
+    && !e?.target?.closest(".component-wrapper")
+  ) {
+    projectStore.clearAllSelectedElement();
+  }
+};
+
 /* 适应大小设置 */
 watch(
   () => stageStore.scale,