|
|
@@ -1,8 +1,9 @@
|
|
|
<template>
|
|
|
<div
|
|
|
- :style="getStyle"
|
|
|
ref="nodeRef"
|
|
|
- :class="schema.type === 'page' ? '' : 'ignore-click widget-wrapper'"
|
|
|
+ :style="getStyle"
|
|
|
+ :class="schema.type === 'page' ? '' : 'ignore-click widget-node'"
|
|
|
+ :widget-id="schema.id"
|
|
|
@click.stop="handleSelect"
|
|
|
v-if="!schema.hidden"
|
|
|
>
|
|
|
@@ -44,11 +45,11 @@
|
|
|
center: true,
|
|
|
middle: true
|
|
|
}"
|
|
|
- :maxSnapElementGuidelineDistance="50"
|
|
|
+ :maxSnapElementGuidelineDistance="100"
|
|
|
:elementGuidelines="elementGridelines"
|
|
|
- :controlPadding="4"
|
|
|
:verticalGuidelines="verticalGuidelines"
|
|
|
:horizontalGuidelines="horizontalGuidelines"
|
|
|
+ :controlPadding="4"
|
|
|
@render="onRender"
|
|
|
@drag="onDrag"
|
|
|
@resize="onResize"
|
|
|
@@ -59,12 +60,14 @@
|
|
|
<script setup lang="ts">
|
|
|
import type { BaseWidget } from '@/types/baseWidget'
|
|
|
import type { Page } from '@/types/page'
|
|
|
+import type { StageState } from './type'
|
|
|
|
|
|
import { computed, type CSSProperties, ref, inject } from 'vue'
|
|
|
import { useDrop } from 'vue-hooks-plus'
|
|
|
import { createWidget } from '@/model'
|
|
|
import LvglWidgets from '@/lvgl-widgets'
|
|
|
import { useProjectStore } from '@/store/modules/project'
|
|
|
+import { useMutationObserver } from '@vueuse/core'
|
|
|
|
|
|
import Moveable from 'vue3-moveable'
|
|
|
import { getAddWidgetIndex } from '@/utils'
|
|
|
@@ -74,6 +77,8 @@ defineOptions({
|
|
|
})
|
|
|
|
|
|
const page = inject<Page>('page')
|
|
|
+const pageState = inject<StageState>('state')
|
|
|
+const pageEl = inject<HTMLElement>('pageEl')
|
|
|
|
|
|
const props = defineProps<{
|
|
|
// 父级容器 拖拽缩放设置
|
|
|
@@ -93,17 +98,6 @@ const nodeRef = ref<HTMLDivElement>()
|
|
|
const selected = computed(() =>
|
|
|
projectStore.activeWidgets.map((item) => item.id).includes(props.schema.id)
|
|
|
)
|
|
|
-// 辅助线
|
|
|
-const verticalGuidelines = computed(() => {
|
|
|
- return projectStore.activePage?.referenceLine
|
|
|
- .filter((item) => item.type === 'vertical')
|
|
|
- .map((item) => item.value)
|
|
|
-})
|
|
|
-const horizontalGuidelines = computed(() => {
|
|
|
- return projectStore.activePage?.referenceLine
|
|
|
- .filter((item) => item.type === 'horizontal')
|
|
|
- .map((item) => item.value)
|
|
|
-})
|
|
|
|
|
|
// 组件样式
|
|
|
const getStyle = computed((): CSSProperties => {
|
|
|
@@ -121,7 +115,48 @@ const getStyle = computed((): CSSProperties => {
|
|
|
})
|
|
|
|
|
|
// 吸附辅助线
|
|
|
-const elementGridelines = ref([])
|
|
|
+const elementGridelines = ref<Element[]>([])
|
|
|
+// 垂直辅助线
|
|
|
+const verticalGuidelines = computed(() => {
|
|
|
+ return (
|
|
|
+ (pageState?.showReferenceLine &&
|
|
|
+ projectStore.activePage?.referenceLine
|
|
|
+ .filter((item) => item.type === 'horizontal')
|
|
|
+ .map((item) => item.value)) ||
|
|
|
+ []
|
|
|
+ )
|
|
|
+})
|
|
|
+// 水平辅助线
|
|
|
+const horizontalGuidelines = computed(() => {
|
|
|
+ return (
|
|
|
+ (pageState?.showReferenceLine &&
|
|
|
+ projectStore.activePage?.referenceLine
|
|
|
+ .filter((item) => item.type === 'vertical')
|
|
|
+ .map((item) => item.value)) ||
|
|
|
+ []
|
|
|
+ )
|
|
|
+})
|
|
|
+
|
|
|
+// 监听页面节点变化 设置元素辅助线
|
|
|
+useMutationObserver(
|
|
|
+ pageEl,
|
|
|
+ (mutations) => {
|
|
|
+ mutations.forEach(() => {
|
|
|
+ const els = document.querySelectorAll('.widget-node')
|
|
|
+ elementGridelines.value = []
|
|
|
+ els.forEach((el) => {
|
|
|
+ // 排除自己
|
|
|
+ if (el.attributes['widget-id']?.value !== props.schema.id) {
|
|
|
+ elementGridelines.value.push(el)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ })
|
|
|
+ },
|
|
|
+ {
|
|
|
+ childList: true,
|
|
|
+ subtree: true
|
|
|
+ }
|
|
|
+)
|
|
|
|
|
|
// 拖拽放置事件处理
|
|
|
useDrop(nodeRef, {
|