调整提示词交互
This commit is contained in:
@@ -16,13 +16,13 @@ const props = defineProps({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
// content: [
|
// content: [
|
||||||
// { id: '1', type: 'text', value: '11111' },
|
// { id: '1', type: 'text', value: '11111' },
|
||||||
// { id: '2', type: 'input', value: '222', placeholder: '[请输入内容]' },
|
// { id: '2', type: 'input', value: '222', placeholder: '[请输入内容]' },
|
||||||
// { id: '3', type: 'text', value: '333333' },
|
// { id: '3', type: 'text', value: '333333' },
|
||||||
// { id: '4', type: 'input', value: '', placeholder: '[请输入内容]' }
|
// { id: '4', type: 'input', value: '', placeholder: '[请输入内容]' }
|
||||||
// ] as ContentItem[]
|
// ] as ContentItem[]
|
||||||
content: props.content
|
content: props.content
|
||||||
})
|
})
|
||||||
|
|
||||||
const editableArea = ref<HTMLElement>()
|
const editableArea = ref<HTMLElement>()
|
||||||
@@ -32,6 +32,12 @@ const cursorState = ref({
|
|||||||
isContainerClick: false
|
isContainerClick: false
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 添加中文输入状态管理
|
||||||
|
const compositionState = reactive({
|
||||||
|
isComposing: false,
|
||||||
|
currentInputIndex: -1
|
||||||
|
})
|
||||||
|
|
||||||
// 检查并删除末尾的空文本框
|
// 检查并删除末尾的空文本框
|
||||||
const removeLastEmptyTextIfNeeded = () => {
|
const removeLastEmptyTextIfNeeded = () => {
|
||||||
const lastItem = content.value[content.value.length - 1]
|
const lastItem = content.value[content.value.length - 1]
|
||||||
@@ -266,12 +272,30 @@ const updateInputDisplay = (index: number) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 输入框内容变化处理
|
|
||||||
const handleInputChange = (index: number, event: Event) => {
|
const handleInputChange = (index: number, event: Event) => {
|
||||||
|
// 如果是中文输入过程中,不处理
|
||||||
|
if (compositionState.isComposing && compositionState.currentInputIndex === index) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const target = event.target as HTMLSpanElement
|
const target = event.target as HTMLSpanElement
|
||||||
const item = content.value[index]
|
const item = content.value[index]
|
||||||
|
|
||||||
// 如果当前显示placeholder,不更新实际值
|
// 如果当前显示placeholder,但内容已改变(比如通过粘贴),清除placeholder
|
||||||
|
if (target.classList.contains('has-placeholder') && target.textContent !== item.placeholder) {
|
||||||
|
target.classList.remove('has-placeholder')
|
||||||
|
const newValue = target.textContent || ''
|
||||||
|
content.value[index].value = newValue
|
||||||
|
|
||||||
|
// 如果粘贴后内容为空,重新显示 placeholder
|
||||||
|
if (newValue.trim() === '' && item.placeholder) {
|
||||||
|
target.classList.add('has-placeholder')
|
||||||
|
target.textContent = item.placeholder
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 正常情况下的处理
|
||||||
if (!target.classList.contains('has-placeholder')) {
|
if (!target.classList.contains('has-placeholder')) {
|
||||||
const newValue = target.textContent || ''
|
const newValue = target.textContent || ''
|
||||||
content.value[index].value = newValue
|
content.value[index].value = newValue
|
||||||
@@ -284,7 +308,33 @@ const handleInputChange = (index: number, event: Event) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 输入框键盘事件
|
// 添加专门的粘贴事件处理
|
||||||
|
const handleInputPaste = (event: ClipboardEvent, index: number) => {
|
||||||
|
const target = event.target as HTMLSpanElement
|
||||||
|
const item = content.value[index]
|
||||||
|
|
||||||
|
// 如果当前显示 placeholder,先清除它
|
||||||
|
if (target.classList.contains('has-placeholder')) {
|
||||||
|
event.preventDefault()
|
||||||
|
target.classList.remove('has-placeholder')
|
||||||
|
target.textContent = ''
|
||||||
|
|
||||||
|
// 获取粘贴的内容
|
||||||
|
const pasteData = event.clipboardData?.getData('text') || ''
|
||||||
|
document.execCommand('insertText', false, pasteData)
|
||||||
|
|
||||||
|
// 更新值
|
||||||
|
const newValue = target.textContent || ''
|
||||||
|
content.value[index].value = newValue
|
||||||
|
|
||||||
|
// 如果粘贴后内容为空,重新显示 placeholder
|
||||||
|
if (newValue.trim() === '' && item.placeholder) {
|
||||||
|
target.classList.add('has-placeholder')
|
||||||
|
target.textContent = item.placeholder
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const handleInputKeydown = (event: KeyboardEvent, index: number) => {
|
const handleInputKeydown = (event: KeyboardEvent, index: number) => {
|
||||||
const target = event.target as HTMLSpanElement
|
const target = event.target as HTMLSpanElement
|
||||||
|
|
||||||
@@ -320,9 +370,76 @@ const handleInputKeydown = (event: KeyboardEvent, index: number) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 添加对 Ctrl+V 的处理
|
||||||
|
else if ((event.ctrlKey || event.metaKey) && event.key === 'v') {
|
||||||
|
// 延迟处理,等待粘贴内容实际插入
|
||||||
|
setTimeout(() => {
|
||||||
|
handlePasteInInput(index, target)
|
||||||
|
}, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handlePasteInInput = (index: number, element: HTMLElement) => {
|
||||||
|
const item = content.value[index]
|
||||||
|
|
||||||
|
// 如果当前显示 placeholder,清除它
|
||||||
|
if (element.classList.contains('has-placeholder')) {
|
||||||
|
element.classList.remove('has-placeholder')
|
||||||
|
// 获取粘贴后的实际内容
|
||||||
|
const newValue = element.textContent || ''
|
||||||
|
content.value[index].value = newValue
|
||||||
|
|
||||||
|
// 如果粘贴后内容为空,重新显示 placeholder
|
||||||
|
if (newValue.trim() === '' && item.placeholder) {
|
||||||
|
element.classList.add('has-placeholder')
|
||||||
|
element.textContent = item.placeholder
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 正常情况,直接更新值
|
||||||
|
const newValue = element.textContent || ''
|
||||||
|
content.value[index].value = newValue
|
||||||
|
|
||||||
|
// 检查是否需要显示 placeholder
|
||||||
|
if (newValue.trim() === '' && item.placeholder) {
|
||||||
|
element.classList.add('has-placeholder')
|
||||||
|
element.textContent = item.placeholder
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加中文输入事件处理
|
||||||
|
const handleCompositionStart = (index: number, event: CompositionEvent) => {
|
||||||
|
compositionState.isComposing = true
|
||||||
|
compositionState.currentInputIndex = index
|
||||||
|
|
||||||
|
const target = event.target as HTMLSpanElement
|
||||||
|
// 如果是placeholder状态,开始中文输入时清除placeholder
|
||||||
|
if (target.classList.contains('has-placeholder')) {
|
||||||
|
target.classList.remove('has-placeholder')
|
||||||
|
target.textContent = ''
|
||||||
|
content.value[index].value = ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleCompositionEnd = (index: number, event: CompositionEvent) => {
|
||||||
|
compositionState.isComposing = false
|
||||||
|
compositionState.currentInputIndex = -1
|
||||||
|
|
||||||
|
const target = event.target as HTMLSpanElement
|
||||||
|
const newValue = target.textContent || ''
|
||||||
|
content.value[index].value = newValue
|
||||||
|
|
||||||
|
// 如果中文输入后内容为空,显示placeholder
|
||||||
|
const item = content.value[index]
|
||||||
|
if (newValue.trim() === '' && item.placeholder) {
|
||||||
|
target.classList.add('has-placeholder')
|
||||||
|
target.textContent = item.placeholder
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleInputBlur = (index: number) => {
|
const handleInputBlur = (index: number) => {
|
||||||
|
compositionState.isComposing = false
|
||||||
|
compositionState.currentInputIndex = -1
|
||||||
updateInputDisplay(index)
|
updateInputDisplay(index)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -433,6 +550,9 @@ defineExpose({
|
|||||||
@input="e => handleInputChange(index, e)"
|
@input="e => handleInputChange(index, e)"
|
||||||
@keydown="e => handleInputKeydown(e, index)"
|
@keydown="e => handleInputKeydown(e, index)"
|
||||||
@blur="() => handleInputBlur(index)"
|
@blur="() => handleInputBlur(index)"
|
||||||
|
@paste="e => handleInputPaste(e, index)"
|
||||||
|
@compositionstart="e => handleCompositionStart(index, e)"
|
||||||
|
@compositionend="e => handleCompositionEnd(index, e)"
|
||||||
></span>
|
></span>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
@@ -478,13 +598,10 @@ defineExpose({
|
|||||||
font-size: 1.8rem;
|
font-size: 1.8rem;
|
||||||
min-width: 2px;
|
min-width: 2px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
/* 确保空文本框也能点击 */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-field {
|
.input-field {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
// background: #e3f2fd;
|
|
||||||
// border: 1px solid #bbdefb;
|
|
||||||
margin: 0 0.2rem;
|
margin: 0 0.2rem;
|
||||||
padding: 0.2rem 1rem;
|
padding: 0.2rem 1rem;
|
||||||
font-size: 1.8rem;
|
font-size: 1.8rem;
|
||||||
@@ -497,7 +614,6 @@ defineExpose({
|
|||||||
|
|
||||||
&.has-placeholder {
|
&.has-placeholder {
|
||||||
color: #b9b9b9;
|
color: #b9b9b9;
|
||||||
// font-style: italic;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -547,7 +663,6 @@ defineExpose({
|
|||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
width: initial;
|
width: initial;
|
||||||
// margin-top: -0.2rem;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
Reference in New Issue
Block a user