Files
FiDA_Front/src/components/Canvas/FlowCanvas/components/nodes/text.vue
X1627315083@163.com 01a843e71f fix
2026-03-12 17:07:04 +08:00

99 lines
2.0 KiB
Vue

<template>
<!-- 文字节点 -->
<div class="text" @mousedown="onMouseDown">
<div
tabindex="0"
class="input"
ref="inputRef"
:contenteditable="active"
@input="onInput"
@blur="onBlur"
@paste.prevent
@keydown.stop
></div>
<span class="delete" @mousedown.stop @click="emit('delete-node')" v-show="active">
<svg-icon name="close" size="7" size-unit="px" />
</span>
</div>
</template>
<script setup lang="ts">
import { reactive, ref, onMounted, nextTick, watch } from 'vue'
const props = defineProps({
active: {
type: Boolean,
default: false
},
data: {
type: Object,
default: () => ({})
}
})
const emit = defineEmits(['update-data', 'delete-node'])
const data = reactive({
text: props.data?.text || '点击编辑文本'
})
const time = ref(null)
const inputRef = ref<any>()
const onInput = () => {
const text = inputRef.value.innerHTML
data.text = text
}
// watch(
// () => props.active,
// (newVal) => {
// if (!newVal) return
// nextTick(() => {
// // 光标定位到文本末尾
// const range = document.createRange()
// const selection = window.getSelection()
// range.selectNodeContents(inputRef.value)
// range.collapse(false)
// selection.removeAllRanges()
// selection.addRange(range)
// })
// }
// )
const onMouseDown = (e: MouseEvent) => {
if (props.active) e.stopPropagation()
}
const onBlur = () => {
// emit('update-data', data)
}
onMounted(() => {
inputRef.value.innerHTML = data.text
emit('update-data', data)
})
defineExpose({ data })
</script>
<style lang="less" scoped>
.text {
user-select: none;
border: 1px solid transparent;
padding: 2px;
position: relative;
&.active {
border-color: #000;
> .input {
cursor: text;
}
}
> .input {
outline: none;
min-width: 2px;
font-size: 16px;
}
> .delete {
position: absolute;
top: 4px;
right: 4px;
transform: translate(100%, -100%);
background-color: #fff;
padding: 2px;
border-radius: 50%;
cursor: pointer;
}
}
</style>