Skip to content

Commit bfdea6a

Browse files
committed
fix: 再次尝试修复双击编辑失效的问题
- 将messageItem的编辑状态改为由父组件传入 - 增加了延迟,防止 blur 事件在虚拟滚动重新计算位置时被意外触发
1 parent f0f9b29 commit bfdea6a

2 files changed

Lines changed: 38 additions & 37 deletions

File tree

src/components/common/MessageItem.vue

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -65,16 +65,16 @@
6565
<div
6666
class="message-content"
6767
:style="computedStyles.contentStyle"
68-
@dblclick.stop="startEditing"
68+
@dblclick.stop="$emit('startEdit', message)"
6969
>
7070
<template v-if="isEditing">
7171
<textarea
7272
ref="editInput"
73-
v-model="editContent"
73+
v-model="editContentLocal"
7474
class="content-editor"
75-
@blur="saveEdit"
76-
@keydown.enter.ctrl="saveEdit"
77-
@keydown.esc="cancelEdit"
75+
@blur="$emit('saveEdit', message.messageId)"
76+
@keydown.enter.ctrl="$emit('saveEdit', message.messageId)"
77+
@keydown.esc="$emit('cancelEdit')"
7878
></textarea>
7979
</template>
8080
<div v-else>
@@ -85,22 +85,25 @@
8585
</template>
8686

8787
<script setup lang="ts">
88-
import { computed, ref, nextTick } from 'vue';
88+
import { computed, ref, nextTick, watch } from 'vue';
8989
import type { Message } from '@/types/log';
9090
import { useStyleStore } from '@/stores/styleStore';
9191
import { formatDate } from '@/utils/date';
9292
import { computeStyleForMessage } from '@/editor/styleEngine';
9393
import { Trash2, Plus, Scissors, ChevronsDown } from '@lucide/vue';
9494
95+
// 加入虚拟滚动之后,把编辑状态放在messageItem里会导致状态丢失
96+
// 统一改成父组件传入
9597
const props = defineProps<{
9698
message: Message;
9799
chunkId: string;
98100
index: number;
99101
isSelected: boolean;
100102
isActive: boolean;
103+
isEditing: boolean;
104+
editingContent: string;
101105
}>();
102106
103-
// 向上事件传递
104107
const emit = defineEmits<{
105108
(e: 'select', event: MouseEvent, messageId: string, index: number): void;
106109
(
@@ -117,7 +120,10 @@ const emit = defineEmits<{
117120
(e: 'actionMerge'): void;
118121
(e: 'actionSplit'): void;
119122
(e: 'actionDelete'): void;
123+
(e: 'startEdit', message: Message): void;
120124
(e: 'updateContent', content: string): void;
125+
(e: 'saveEdit', messageId: string): void;
126+
(e: 'cancelEdit'): void;
121127
}>();
122128
123129
const styleStore = useStyleStore();
@@ -161,35 +167,29 @@ const isHidden = computed(() => {
161167
);
162168
});
163169
164-
const isEditing = ref(false);
165-
const editContent = ref('');
170+
const editContentLocal = computed({
171+
get: () => props.editingContent,
172+
set: (val) => emit('updateContent', val),
173+
});
166174
const editInput = ref<HTMLTextAreaElement | null>(null);
167-
168-
function startEditing() {
169-
editContent.value = props.message.content;
170-
isEditing.value = true;
171-
nextTick(() => {
172-
if (editInput.value) {
173-
editInput.value.focus();
174-
editInput.value.setSelectionRange(
175-
editContent.value.length,
176-
editContent.value.length,
177-
);
175+
watch(
176+
() => props.isEditing,
177+
async (newVal) => {
178+
if (newVal) {
179+
await nextTick();
180+
setTimeout(() => {
181+
if (editInput.value) {
182+
editInput.value.focus();
183+
editInput.value.setSelectionRange(
184+
props.editingContent.length,
185+
props.editingContent.length,
186+
);
187+
}
188+
}, 50);
189+
// 这里增加延迟,确保虚拟滚动完全稳定,避免textarea闪现
178190
}
179-
});
180-
}
181-
182-
function saveEdit() {
183-
if (!isEditing.value) return;
184-
if (editContent.value !== props.message.content) {
185-
emit('updateContent', editContent.value);
186-
}
187-
isEditing.value = false;
188-
}
189-
190-
function cancelEdit() {
191-
isEditing.value = false;
192-
}
191+
},
192+
);
193193
</script>
194194

195195
<style scoped>

src/components/workspace/ChunkView.vue

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
:item="msg"
5353
:key="msg.messageId"
5454
:active="active"
55-
:size-dependencies="[msg.content]"
55+
:size-dependencies="[msg.content, editingMessageId]"
5656
:data-index="index"
5757
class="message-slot"
5858
>
@@ -89,6 +89,7 @@
8989
@start-edit="handleStartEdit"
9090
@update-content="handleUpdateContent"
9191
@save-edit="handleSaveEdit"
92+
@cancel-edit="editingMessageId = null"
9293
/>
9394
</DynamicScrollerItem>
9495
</template>
@@ -243,7 +244,7 @@ function handleUpdateContent(val: string) {
243244
244245
function handleSaveEdit(messageId: string) {
245246
const msg = messages.value.find((m) => m.messageId === messageId);
246-
if (msg) {
247+
if (msg && msg.content !== editingContent.value) {
247248
msg.content = editingContent.value;
248249
}
249250
editingMessageId.value = null;
@@ -333,7 +334,7 @@ function handleActionDelete(msgId: string) {
333334
flex: 1;
334335
display: flex;
335336
flex-direction: column;
336-
overflow: hidden; /* 让子元素 scroller 去处理 y 轴滚动 */
337+
overflow: hidden;
337338
padding: 0px 0px;
338339
position: relative;
339340
background-color: var(--bg-workspace);

0 commit comments

Comments
 (0)