This commit is contained in:
lzp
2026-03-05 13:46:10 +08:00
parent b3051c15de
commit 232cac5805
6 changed files with 39 additions and 33 deletions

View File

@@ -8,7 +8,7 @@
:position="handle.position" :position="handle.position"
:connectable="false" :connectable="false"
/> />
<div class="item"> <div class="item" @mousedown="(e) => stateManager.setActiveNodeID(node.id)">
<slot></slot> <slot></slot>
</div> </div>
<div class="add" @mousedown.stop v-if="isAdd" @click="onAdd"> <div class="add" @mousedown.stop v-if="isAdd" @click="onAdd">

View File

@@ -143,7 +143,7 @@
<style lang="less" scoped> <style lang="less" scoped>
.card { .card {
width: 250px; width: 244px;
height: auto; height: auto;
--border-radius: 16px; --border-radius: 16px;
border-radius: var(--border-radius); border-radius: var(--border-radius);
@@ -151,6 +151,9 @@
box-shadow: 0 15px 21px 0 rgba(0, 0, 0, 0.05); box-shadow: 0 15px 21px 0 rgba(0, 0, 0, 0.05);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
&.active {
box-shadow: 0 15px 21px 0 rgba(0, 0, 0, 0.05), 0 0 0 2px #fae5d8;
}
> .header { > .header {
border-radius: var(--border-radius) var(--border-radius) 0 0; border-radius: var(--border-radius) var(--border-radius) 0 0;
height: 50px; height: 50px;

View File

@@ -1,17 +1,11 @@
<template> <template>
<!-- 结果图片 --> <!-- 结果图片 -->
<div <div class="text" @mousedown="onMouseDown">
class="text"
:class="{ edit }"
@click="onClick"
@mousedown="onMouseDown"
@dblclick="onDoubleClick"
>
<div <div
tabindex="0" tabindex="0"
class="input" class="input"
ref="inputRef" ref="inputRef"
:contenteditable="edit" :contenteditable="active"
@input="onInput" @input="onInput"
@blur="onBlur" @blur="onBlur"
@paste.prevent @paste.prevent
@@ -20,8 +14,12 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { reactive, ref, onMounted, nextTick } from 'vue' import { reactive, ref, onMounted, nextTick, watch } from 'vue'
const props = defineProps({ const props = defineProps({
active: {
type: Boolean,
default: false
},
data: { data: {
type: Object, type: Object,
default: () => ({}) default: () => ({})
@@ -31,7 +29,6 @@
const data = reactive({ const data = reactive({
text: props.data?.text || '点击编辑文本' text: props.data?.text || '点击编辑文本'
}) })
const edit = ref(false)
const time = ref(null) const time = ref(null)
const inputRef = ref<any>() const inputRef = ref<any>()
const onInput = () => { const onInput = () => {
@@ -39,27 +36,26 @@
data.text = text data.text = text
emit('update-data', data) emit('update-data', data)
} }
const onBlur = () => { // watch(
edit.value = false // () => props.active,
} // (newVal) => {
const onClick = () => { // if (!newVal) return
if (edit.value) return // nextTick(() => {
edit.value = true // // 光标定位到文本末尾
nextTick(() => { // const range = document.createRange()
// 光标定位到文本末尾 // const selection = window.getSelection()
const range = document.createRange() // range.selectNodeContents(inputRef.value)
const selection = window.getSelection() // range.collapse(false)
range.selectNodeContents(inputRef.value) // selection.removeAllRanges()
range.collapse(false) // selection.addRange(range)
selection.removeAllRanges() // })
selection.addRange(range) // }
}) // )
}
const onDoubleClick = () => {
clearTimeout(time.value)
}
const onMouseDown = (e: MouseEvent) => { const onMouseDown = (e: MouseEvent) => {
if (edit.value) e.stopPropagation() if (props.active) e.stopPropagation()
}
const onBlur = () => {
// emit('update-data', data)
} }
onMounted(() => { onMounted(() => {
inputRef.value.innerHTML = data.text inputRef.value.innerHTML = data.text
@@ -73,7 +69,7 @@
user-select: none; user-select: none;
border: 1px solid transparent; border: 1px solid transparent;
padding: 2px; padding: 2px;
&.edit { &.active {
border-color: #000; border-color: #000;
> .input { > .input {
cursor: text; cursor: text;

View File

@@ -27,6 +27,8 @@
> >
<component <component
:is="components[node.data.component]" :is="components[node.data.component]"
:class="{ active: stateManager.activeNodeID.value === node.id }"
:active="stateManager.activeNodeID.value === node.id"
:node="node" :node="node"
:config="node.data" :config="node.data"
:data="node.data.data" :data="node.data.data"

View File

@@ -26,6 +26,7 @@ export class EventManager {
} }
/** 处理点击 */ /** 处理点击 */
handleClick(event: any) { handleClick(event: any) {
this.stateManager.setActiveNodeID("")
const tool = this.stateManager.tool.value const tool = this.stateManager.tool.value
if (tool === TOOLS.TEXT) { if (tool === TOOLS.TEXT) {
const { x, y, zoom } = this.vueFlow.value.viewport const { x, y, zoom } = this.vueFlow.value.viewport

View File

@@ -10,6 +10,7 @@ export interface NodesItem {
} }
export class StateManager { export class StateManager {
vueFlow: any vueFlow: any
activeNodeID: any
nodes: any nodes: any
nodes_: any nodes_: any
edges: any edges: any
@@ -49,6 +50,7 @@ export class StateManager {
this.historyList = ref([]) this.historyList = ref([])
this.historyIndex = ref(0) this.historyIndex = ref(0)
this.activeNodeID = ref("")
this.nodes = ref<NodesItem[]>([]); this.nodes = ref<NodesItem[]>([]);
this.nodes_ = computed(() => { this.nodes_ = computed(() => {
return this.nodes.value.map((node, index) => { return this.nodes.value.map((node, index) => {
@@ -90,6 +92,8 @@ export class StateManager {
}) })
} }
/** 设置激活节点 */
setActiveNodeID(id: string) { this.activeNodeID.value = id }
/** 添加节点 */ /** 添加节点 */
addNode(node: NodesItem) { addNode(node: NodesItem) {
this.nodes.value.push(node); this.nodes.value.push(node);